Basic crashing text rendering
This commit is contained in:
@@ -28,3 +28,6 @@
|
|||||||
[submodule "external/ttf-parser"]
|
[submodule "external/ttf-parser"]
|
||||||
path = external/ttf-parser
|
path = external/ttf-parser
|
||||||
url = git@github.com:kv01/ttf-parser.git
|
url = git@github.com:kv01/ttf-parser.git
|
||||||
|
[submodule "external/freetype"]
|
||||||
|
path = external/freetype
|
||||||
|
url = https://gitlab.freedesktop.org/freetype/freetype.git
|
||||||
|
|||||||
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
"name": "Win32",
|
"name": "Win32",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/src/**",
|
"${workspaceFolder}/src/**",
|
||||||
"${workspaceFolder}/external/**"
|
"${workspaceFolder}/src/Engine"
|
||||||
],
|
],
|
||||||
"defines": [
|
"defines": [
|
||||||
"_DEBUG",
|
"_DEBUG",
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ set(JSON_ROOT ${EXTERNAL_ROOT}/json)
|
|||||||
set(KTX_ROOT ${EXTERNAL_ROOT}/ktx)
|
set(KTX_ROOT ${EXTERNAL_ROOT}/ktx)
|
||||||
set(STB_ROOT ${EXTERNAL_ROOT}/stb)
|
set(STB_ROOT ${EXTERNAL_ROOT}/stb)
|
||||||
set(TTFPARSER_ROOT ${EXTERNAL_ROOT}/ttf-parser)
|
set(TTFPARSER_ROOT ${EXTERNAL_ROOT}/ttf-parser)
|
||||||
|
set(FREETYPE_ROOT ${EXTERNAL_ROOT}/freetype)
|
||||||
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
|
set(SPIRV_ROOT ${EXTERNAL_ROOT}/SPIRV-Cross)
|
||||||
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ find_package(Threads REQUIRED)
|
|||||||
find_package(Assimp REQUIRED)
|
find_package(Assimp REQUIRED)
|
||||||
find_package(JSON REQUIRED)
|
find_package(JSON REQUIRED)
|
||||||
find_package(GLFW REQUIRED)
|
find_package(GLFW REQUIRED)
|
||||||
|
find_package(FreeType REQUIRED)
|
||||||
find_package(TTFParser REQUIRED)
|
find_package(TTFParser REQUIRED)
|
||||||
find_package(GLM REQUIRED)
|
find_package(GLM REQUIRED)
|
||||||
find_package(KTX REQUIRED)
|
find_package(KTX REQUIRED)
|
||||||
@@ -130,6 +132,7 @@ if(WIN32)
|
|||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:Engine>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:Engine>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:Engine>
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FREETYPE_BINARY} $<TARGET_FILE_DIR:Engine>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:Engine>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:Engine>
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_LLVM} $<TARGET_FILE_DIR:Engine>
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_LLVM} $<TARGET_FILE_DIR:Engine>
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ set(GLFW_VULKAN_STATIC OFF CACHE BOOL "GLFW vulkan static")
|
|||||||
add_subdirectory(${GLFW_ROOT} ${GLFW_ROOT})
|
add_subdirectory(${GLFW_ROOT} ${GLFW_ROOT})
|
||||||
|
|
||||||
#--------------FreeType------------------------------
|
#--------------FreeType------------------------------
|
||||||
#list(APPEND DEPENDENCIES freetype)
|
list(APPEND DEPENDENCIES freetype)
|
||||||
|
|
||||||
#add_subdirectory(${FREETYPE_ROOT} ${FREETYPE_ROOT})
|
add_subdirectory(${FREETYPE_ROOT} ${FREETYPE_ROOT})
|
||||||
|
|
||||||
#--------------SLang------------------------------
|
#--------------SLang------------------------------
|
||||||
list(APPEND DEPENDENCIES slang)
|
list(APPEND DEPENDENCIES slang)
|
||||||
@@ -73,7 +73,7 @@ if(WIN32)
|
|||||||
ExternalProject_Add(slang
|
ExternalProject_Add(slang
|
||||||
SOURCE_DIR ${SLANG_ROOT}
|
SOURCE_DIR ${SLANG_ROOT}
|
||||||
BINARY_DIR ${SLANG_ROOT}
|
BINARY_DIR ${SLANG_ROOT}
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND premake.bat vs2019 --file=${CMAKE_SOURCE_DIR}/external/slang/premake5.lua gmake --arch=${CMAKE_PLATFORM} --deps=true
|
||||||
BUILD_COMMAND msbuild slang.sln -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM}
|
BUILD_COMMAND msbuild slang.sln -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM}
|
||||||
INSTALL_COMMAND "")
|
INSTALL_COMMAND "")
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
|
|||||||
+1
Submodule external/freetype added at e50798b720
Vendored
+1
-1
Submodule external/slang updated: 858c7c57b1...2e1a84add5
Binary file not shown.
@@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
struct GlyphData
|
||||||
|
{
|
||||||
|
float2 bearing;
|
||||||
|
float2 size;
|
||||||
|
};
|
||||||
|
struct ViewData
|
||||||
|
{
|
||||||
|
float4x4 projectionMatrix;
|
||||||
|
}
|
||||||
|
layout(set = 0, binding = 0)
|
||||||
|
ConstantBuffer<ViewData> viewData;
|
||||||
|
layout(set = 0, binding = 1)
|
||||||
|
SamplerState glyphSampler;
|
||||||
|
layout(set = 0, binding = 2)
|
||||||
|
StructuredBuffer<GlyphData> glyphData;
|
||||||
|
layout(set = 1)
|
||||||
|
Texture2D glyphTextures[];
|
||||||
|
layout(push_constant)
|
||||||
|
float scale;
|
||||||
|
|
||||||
|
struct VertexStageInput
|
||||||
|
{
|
||||||
|
uint glyphIndex;
|
||||||
|
float2 position;
|
||||||
|
uint vertexId : SV_VertexID;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexStageOutput
|
||||||
|
{
|
||||||
|
float4 position : SV_Position;
|
||||||
|
float2 uvCoords : TEXCOORD;
|
||||||
|
uint glyphIndex : GLYPHINDEX;
|
||||||
|
};
|
||||||
|
|
||||||
|
[shader("vertex")]
|
||||||
|
VertexStageOutput vertexMain(VertexStageInput input)
|
||||||
|
{
|
||||||
|
GlyphData glyph = glyphData[input.glyphIndex];
|
||||||
|
|
||||||
|
float xpos = input.position.x + glyph.bearing.x * scale;
|
||||||
|
float ypos = input.position.y - (glyph.size.y - glyph.bearing.y) * scale;
|
||||||
|
|
||||||
|
float w = glyph.size.x * scale;
|
||||||
|
float h = glyph.size.y * scale;
|
||||||
|
|
||||||
|
float4 coordinates[4] = {
|
||||||
|
float4(xpos, ypos + h, 0, 0),
|
||||||
|
float4(xpos, ypos, 0, 1),
|
||||||
|
float4(xpos + w, ypos, 1, 0),
|
||||||
|
float4(xpos + w, ypos + h, 1, 1)
|
||||||
|
};
|
||||||
|
float4 vertex = coordinates[input.vertexId];
|
||||||
|
VertexStageOutput output;
|
||||||
|
output.uvCoords = vertex.zw;
|
||||||
|
output.position = mul(viewData.projectionMatrix, float4(vertex.xy, 0, 1));
|
||||||
|
output.glyphIndex = input.glyphIndex;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("fragment")]
|
||||||
|
float4 fragmentMain(
|
||||||
|
float4 position : SV_Position,
|
||||||
|
float2 uvCoords : TEXCOORD,
|
||||||
|
uint glyphIndex : GLYPHINDEX
|
||||||
|
) : SV_Target
|
||||||
|
{
|
||||||
|
return glyphTextures[glyphIndex].Sample(glyphSampler, uvCoords);
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ VertexStageOutput vertexMain(uint vertexId : SV_VertexID)
|
|||||||
VertexStageOutput output;
|
VertexStageOutput output;
|
||||||
output.uvCoords = coordinates[vertexId];
|
output.uvCoords = coordinates[vertexId];
|
||||||
output.position = float4(output.uvCoords * 2 - 1, 1, 1);
|
output.position = float4(output.uvCoords * 2 - 1, 1, 1);
|
||||||
output.position.y = -output.position.y;
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
slangc ForwardPlus.slang -target spirv -entry vertexMain -profile vs_6_0 -o vertex.spv -I lib/ -D USE_INSTANCING=0 -D NUM_MATERIAL_TEXCOORDS=1
|
slangc TextPass.slang -target glsl -entry vertexMain -profile vs_6_0 -o vertex.glsl -I lib/ -D INDEX_VIEW_PARAMS=0
|
||||||
slangc ForwardPlus.slang -target spirv -entry fragmentMain -profile ps_6_0 -o fragment.spv -I lib/ -D USE_INSTANCING=0 -D NUM_MATERIAL_TEXCOORDS=1
|
slangc TextPass.slang -target glsl -entry fragmentMain -profile ps_6_0 -o fragment.glsl -I lib/ -D INDEX_VIEW_PARAMS=0
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#version 450
|
||||||
|
layout(row_major) uniform;
|
||||||
|
layout(row_major) buffer;
|
||||||
|
|
||||||
|
#line 61 0
|
||||||
|
layout(location = 0)
|
||||||
|
out vec4 _S1;
|
||||||
|
|
||||||
|
|
||||||
|
#line 61
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
#line 61
|
||||||
|
_S1 = vec4(float(0), float(1), float(0), float(1));
|
||||||
|
|
||||||
|
#line 61
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,114 @@
|
|||||||
|
#version 450
|
||||||
|
layout(row_major) uniform;
|
||||||
|
layout(row_major) buffer;
|
||||||
|
|
||||||
|
#line 7 0
|
||||||
|
struct GlyphData_0
|
||||||
|
{
|
||||||
|
vec2 bearing_0;
|
||||||
|
vec2 size_0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
layout(std430, binding = 1) readonly buffer _S1 {
|
||||||
|
GlyphData_0 _data[];
|
||||||
|
} glyphData_0;
|
||||||
|
|
||||||
|
#line 1
|
||||||
|
struct ViewParameter_0
|
||||||
|
{
|
||||||
|
mat4x4 projectionMatrix_0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(binding = 0)
|
||||||
|
layout(std140) uniform _S2
|
||||||
|
{
|
||||||
|
ViewParameter_0 _data;
|
||||||
|
} gViewParams_0;
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(location = 0)
|
||||||
|
out vec2 _S3;
|
||||||
|
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(location = 1)
|
||||||
|
out uint _S4;
|
||||||
|
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(location = 0)
|
||||||
|
in uint _S5;
|
||||||
|
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(location = 1)
|
||||||
|
in vec2 _S6;
|
||||||
|
|
||||||
|
|
||||||
|
#line 5
|
||||||
|
layout(location = 2)
|
||||||
|
in float _S7;
|
||||||
|
|
||||||
|
|
||||||
|
#line 20
|
||||||
|
struct VertexStageInput_0
|
||||||
|
{
|
||||||
|
uint glyphIndex_0;
|
||||||
|
vec2 position_0;
|
||||||
|
float scale_0;
|
||||||
|
uint vertexId_0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexStageOutput_0
|
||||||
|
{
|
||||||
|
vec4 position_1;
|
||||||
|
vec2 uvCoords_0;
|
||||||
|
uint glyphIndex_1;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
|
||||||
|
#line 36
|
||||||
|
VertexStageInput_0 _S8 = VertexStageInput_0(_S5, _S6, _S7, uint(gl_VertexIndex));
|
||||||
|
|
||||||
|
GlyphData_0 glyph_0 = ((glyphData_0)._data[(_S8.glyphIndex_0)]);
|
||||||
|
|
||||||
|
float xpos_0 = _S8.position_0.x + glyph_0.bearing_0.x * _S8.scale_0;
|
||||||
|
float ypos_0 = _S8.position_0.y - (glyph_0.size_0.y - glyph_0.bearing_0.y) * _S8.scale_0;
|
||||||
|
|
||||||
|
float w_0 = glyph_0.size_0.x * _S8.scale_0;
|
||||||
|
|
||||||
|
|
||||||
|
vec4 coordinates_0[4] = { vec4(xpos_0, ypos_0 + glyph_0.size_0.y * _S8.scale_0, float(0), float(0)), vec4(xpos_0, ypos_0, float(0), float(1)), vec4(xpos_0 + w_0, ypos_0, float(1), float(0)), vec4(xpos_0 + w_0, ypos_0 + w_0, float(1), float(1)) };
|
||||||
|
|
||||||
|
#line 46
|
||||||
|
vec4 vertex_0 = coordinates_0[_S8.vertexId_0];
|
||||||
|
|
||||||
|
#line 53
|
||||||
|
VertexStageOutput_0 output_0;
|
||||||
|
output_0.uvCoords_0 = vertex_0.zw;
|
||||||
|
vec4 _S9 = (((vec4(vertex_0.xy, float(0), float(1))) * (gViewParams_0._data.projectionMatrix_0)));
|
||||||
|
|
||||||
|
#line 55
|
||||||
|
output_0.position_1 = _S9;
|
||||||
|
output_0.glyphIndex_1 = _S8.glyphIndex_0;
|
||||||
|
VertexStageOutput_0 _S10 = output_0;
|
||||||
|
|
||||||
|
#line 57
|
||||||
|
gl_Position = _S10.position_1;
|
||||||
|
|
||||||
|
#line 57
|
||||||
|
_S3 = _S10.uvCoords_0;
|
||||||
|
|
||||||
|
#line 57
|
||||||
|
_S4 = _S10.glyphIndex_1;
|
||||||
|
|
||||||
|
#line 57
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
#include "FontAsset.h"
|
#include "FontAsset.h"
|
||||||
#include "Graphics/GraphicsResources.h"
|
#include "Graphics/GraphicsResources.h"
|
||||||
#define TTF_FONT_PARSER_IMPLEMENTATION
|
#include <ft2build.h>
|
||||||
#include "ttfParser.h"
|
#include FT_FREETYPE_H
|
||||||
|
#include "Window/WindowManager.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
@@ -31,20 +32,30 @@ void FontAsset::save()
|
|||||||
|
|
||||||
void FontAsset::load()
|
void FontAsset::load()
|
||||||
{
|
{
|
||||||
TTFFontParser::FontData font_data;
|
FT_Library ft;
|
||||||
int8_t error = TTFFontParser::parse_file(getFullPath().c_str(), &font_data, [](void*, void*, int){}, nullptr);
|
assert(!FT_Init_FreeType(&ft));
|
||||||
assert(!error);
|
FT_Face face;
|
||||||
for(auto pair : font_data.glyphs)
|
assert(!FT_New_Face(ft, getFullPath().c_str(), 0, &face));
|
||||||
|
FT_Set_Pixel_Sizes(face, 0, 48);
|
||||||
|
for(uint8 c = 0; c < 128; ++c)
|
||||||
{
|
{
|
||||||
const TTFFontParser::Glyph& glyphData = pair.second;
|
Gfx::PGraphics graphics = WindowManager::getGraphics();
|
||||||
Glyph& glyph = glyphs[pair.first];
|
if(FT_Load_Char(face, c, FT_LOAD_RENDER))
|
||||||
glyph.advance = glyphData.advance_width;
|
{
|
||||||
std::memcpy(glyph.boundingBox, glyphData.bounding_box, sizeof(glyphData.bounding_box));
|
std::cout << "error loading " << (char)c << std::endl;
|
||||||
glyph.center = Vector2(glyphData.glyph_center.x, glyphData.glyph_center.y);
|
}
|
||||||
glyph.index = glyphData.glyph_index;
|
TextureCreateInfo imageData;
|
||||||
glyph.leftSideBearing = glyphData.left_side_bearing;
|
imageData.format = Gfx::SE_FORMAT_R8_UINT;
|
||||||
glyph.numContours = glyphData.num_contours;
|
imageData.width = face->glyph->bitmap.width;
|
||||||
Array<float> curveTextureData;
|
imageData.height = face->glyph->bitmap.rows;
|
||||||
|
imageData.resourceData.data = face->glyph->bitmap.buffer;
|
||||||
|
imageData.resourceData.size = imageData.width * imageData.height;
|
||||||
|
Glyph& glyph = glyphs[c];
|
||||||
|
glyph.texture = graphics->createTexture2D(imageData);
|
||||||
|
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
|
||||||
|
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
|
||||||
|
glyph.advance = face->glyph->advance.x;
|
||||||
}
|
}
|
||||||
|
FT_Done_Face(face);
|
||||||
|
FT_Done_FreeType(ft);
|
||||||
}
|
}
|
||||||
@@ -13,18 +13,16 @@ public:
|
|||||||
virtual ~FontAsset();
|
virtual ~FontAsset();
|
||||||
virtual void save() override;
|
virtual void save() override;
|
||||||
virtual void load() override;
|
virtual void load() override;
|
||||||
private:
|
|
||||||
struct Glyph
|
struct Glyph
|
||||||
{
|
{
|
||||||
int16 index;
|
Gfx::PTexture2D texture;
|
||||||
int16 numContours;
|
IVector2 size;
|
||||||
uint16 advance;
|
IVector2 bearing;
|
||||||
int16 leftSideBearing;
|
uint32 advance;
|
||||||
int16 boundingBox[4];
|
|
||||||
Vector2 center;
|
|
||||||
Gfx::PTexture2D curveTexture;
|
|
||||||
Gfx::PTexture2D bandTexture;
|
|
||||||
};
|
};
|
||||||
|
const Map<uint32, Glyph> getGlyphData() const { return glyphs; }
|
||||||
|
private:
|
||||||
Map<uint32, Glyph> glyphs;
|
Map<uint32, Glyph> glyphs;
|
||||||
};
|
};
|
||||||
DECLARE_REF(FontAsset)
|
DECLARE_REF(FontAsset)
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Window/WindowManager.h"
|
#include "Window/WindowManager.h"
|
||||||
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
|
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
|
||||||
|
#include "ktx.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
#include <stb_image_write.h>
|
#include <stb_image_write.h>
|
||||||
|
#include "ktx.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
|
|||||||
+28
-25
@@ -198,7 +198,7 @@ public:
|
|||||||
using reverse_iterator = std::reverse_iterator<iterator>;
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
Map()
|
constexpr Map() noexcept
|
||||||
: root(-1)
|
: root(-1)
|
||||||
, beginIt(-1)
|
, beginIt(-1)
|
||||||
, endIt(-1)
|
, endIt(-1)
|
||||||
@@ -207,8 +207,7 @@ public:
|
|||||||
, comp(Compare())
|
, comp(Compare())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
explicit Map(const Compare& comp,
|
constexpr explicit Map(const Compare& comp, const Allocator& alloc = Allocator()) noexcept(noexcept(Allocator()))
|
||||||
const Allocator& alloc = Allocator())
|
|
||||||
: nodeContainer(alloc)
|
: nodeContainer(alloc)
|
||||||
, root(-1)
|
, root(-1)
|
||||||
, beginIt(-1)
|
, beginIt(-1)
|
||||||
@@ -218,7 +217,7 @@ public:
|
|||||||
, comp(comp)
|
, comp(comp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
explicit Map(const Allocator& alloc)
|
constexpr explicit Map(const Allocator& alloc) noexcept(noexcept(Compare))
|
||||||
: nodeContainer(alloc)
|
: nodeContainer(alloc)
|
||||||
, root(-1)
|
, root(-1)
|
||||||
, beginIt(-1)
|
, beginIt(-1)
|
||||||
@@ -228,7 +227,7 @@ public:
|
|||||||
, comp(Compare())
|
, comp(Compare())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Map(const Map& other)
|
constexpr Map(const Map& other)
|
||||||
: nodeContainer(other.nodeContainer)
|
: nodeContainer(other.nodeContainer)
|
||||||
, root(other.root)
|
, root(other.root)
|
||||||
, _size(other._size)
|
, _size(other._size)
|
||||||
@@ -236,18 +235,18 @@ public:
|
|||||||
{
|
{
|
||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
}
|
}
|
||||||
Map(Map&& other)
|
constexpr Map(Map&& other) noexcept
|
||||||
: nodeContainer(other.nodeContainer)
|
: nodeContainer(std::move(other.nodeContainer))
|
||||||
, root(std::move(other.root))
|
, root(std::move(other.root))
|
||||||
, _size(std::move(other._size))
|
, _size(std::move(other._size))
|
||||||
, comp(std::move(other.comp))
|
, comp(std::move(other.comp))
|
||||||
{
|
{
|
||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
}
|
}
|
||||||
~Map()
|
constexpr ~Map() noexcept
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
Map& operator=(const Map& other)
|
constexpr Map& operator=(const Map& other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
@@ -259,7 +258,7 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Map& operator=(Map&& other)
|
constexpr Map& operator=(Map&& other)
|
||||||
{
|
{
|
||||||
if(this != &other)
|
if(this != &other)
|
||||||
{
|
{
|
||||||
@@ -271,7 +270,7 @@ public:
|
|||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline mapped_type& operator[](const key_type& key)
|
constexpr mapped_type& operator[](const key_type& key)
|
||||||
{
|
{
|
||||||
root = splay(root, key);
|
root = splay(root, key);
|
||||||
if (!isValid(root)
|
if (!isValid(root)
|
||||||
@@ -284,7 +283,7 @@ public:
|
|||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
return getNode(root)->pair.value;
|
return getNode(root)->pair.value;
|
||||||
}
|
}
|
||||||
inline mapped_type& operator[](key_type&& key)
|
constexpr mapped_type& operator[](key_type&& key)
|
||||||
{
|
{
|
||||||
root = splay(root, std::move(key));
|
root = splay(root, std::move(key));
|
||||||
if (!isValid(root)
|
if (!isValid(root)
|
||||||
@@ -297,7 +296,7 @@ public:
|
|||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
return getNode(root)->pair.value;
|
return getNode(root)->pair.value;
|
||||||
}
|
}
|
||||||
iterator find(const key_type& key)
|
constexpr iterator find(const key_type& key)
|
||||||
{
|
{
|
||||||
root = splay(root, key);
|
root = splay(root, key);
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
@@ -309,7 +308,7 @@ public:
|
|||||||
}
|
}
|
||||||
return iterator(root, &nodeContainer);
|
return iterator(root, &nodeContainer);
|
||||||
}
|
}
|
||||||
iterator find(key_type&& key)
|
constexpr iterator find(key_type&& key)
|
||||||
{
|
{
|
||||||
root = splay(root, std::move(key));
|
root = splay(root, std::move(key));
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
@@ -321,30 +320,34 @@ public:
|
|||||||
}
|
}
|
||||||
return iterator(root, &nodeContainer);
|
return iterator(root, &nodeContainer);
|
||||||
}
|
}
|
||||||
iterator erase(const key_type& key)
|
constexpr iterator erase(const key_type& key)
|
||||||
{
|
{
|
||||||
root = remove(root, key);
|
root = remove(root, key);
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
return iterator(root, &nodeContainer);
|
return iterator(root, &nodeContainer);
|
||||||
}
|
}
|
||||||
iterator erase(K&& key)
|
constexpr iterator erase(key_type&& key)
|
||||||
{
|
{
|
||||||
root = remove(root, std::move(key));
|
root = remove(root, std::move(key));
|
||||||
refreshIterators();
|
refreshIterators();
|
||||||
return iterator(root, &nodeContainer);
|
return iterator(root, &nodeContainer);
|
||||||
}
|
}
|
||||||
void clear()
|
constexpr void clear()
|
||||||
{
|
{
|
||||||
nodeContainer.clear();
|
nodeContainer.clear();
|
||||||
root = -1;
|
root = -1;
|
||||||
_size = 0;
|
_size = 0;
|
||||||
markIteratorsDirty();
|
markIteratorsDirty();
|
||||||
}
|
}
|
||||||
bool exists(key_type&& key)
|
constexpr bool exists(const key_type& key)
|
||||||
{
|
{
|
||||||
return find(std::forward<K>(key)) != endIt;
|
return find(key) != endIt;
|
||||||
}
|
}
|
||||||
iterator begin()
|
constexpr bool exists(key_type&& key)
|
||||||
|
{
|
||||||
|
return find(std::move(key)) != endIt;
|
||||||
|
}
|
||||||
|
constexpr iterator begin()
|
||||||
{
|
{
|
||||||
if(iteratorsDirty)
|
if(iteratorsDirty)
|
||||||
{
|
{
|
||||||
@@ -352,7 +355,7 @@ public:
|
|||||||
}
|
}
|
||||||
return beginIt;
|
return beginIt;
|
||||||
}
|
}
|
||||||
iterator end()
|
constexpr iterator end()
|
||||||
{
|
{
|
||||||
if(iteratorsDirty)
|
if(iteratorsDirty)
|
||||||
{
|
{
|
||||||
@@ -360,7 +363,7 @@ public:
|
|||||||
}
|
}
|
||||||
return endIt;
|
return endIt;
|
||||||
}
|
}
|
||||||
iterator begin() const
|
constexpr iterator begin() const
|
||||||
{
|
{
|
||||||
if(iteratorsDirty)
|
if(iteratorsDirty)
|
||||||
{
|
{
|
||||||
@@ -368,7 +371,7 @@ public:
|
|||||||
}
|
}
|
||||||
return beginIt;
|
return beginIt;
|
||||||
}
|
}
|
||||||
iterator end() const
|
constexpr iterator end() const
|
||||||
{
|
{
|
||||||
if(iteratorsDirty)
|
if(iteratorsDirty)
|
||||||
{
|
{
|
||||||
@@ -376,11 +379,11 @@ public:
|
|||||||
}
|
}
|
||||||
return endIt;
|
return endIt;
|
||||||
}
|
}
|
||||||
bool empty() const
|
constexpr bool empty() const
|
||||||
{
|
{
|
||||||
return nodeContainer.empty();
|
return nodeContainer.empty();
|
||||||
}
|
}
|
||||||
size_type size() const
|
constexpr size_type size() const
|
||||||
{
|
{
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "Containers/Array.h"
|
#include "Containers/Array.h"
|
||||||
#include "VertexShaderInput.h"
|
#include "VertexShaderInput.h"
|
||||||
#include "ShaderCompiler.h"
|
#include "ShaderCompiler.h"
|
||||||
#include "ktx.h"
|
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1404,6 +1404,19 @@ typedef enum SeDescriptorType
|
|||||||
SE_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
|
SE_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
|
||||||
} SeDescriptorType;
|
} SeDescriptorType;
|
||||||
|
|
||||||
|
typedef enum SeDescriptorBindingFlagBits {
|
||||||
|
SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT = 0x00000001,
|
||||||
|
SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT = 0x00000002,
|
||||||
|
SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT = 0x00000004,
|
||||||
|
SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT = 0x00000008,
|
||||||
|
SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT,
|
||||||
|
SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT_EXT = SE_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
|
||||||
|
SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT_EXT = SE_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT,
|
||||||
|
SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT_EXT = SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT,
|
||||||
|
SE_DESCRIPTOR_BINDING_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
|
||||||
|
} SeDescriptorBindingFlagBits;
|
||||||
|
typedef SeFlags SeDescriptorBindingFlags;
|
||||||
|
|
||||||
typedef enum SeAttachmentLoadOp
|
typedef enum SeAttachmentLoadOp
|
||||||
{
|
{
|
||||||
SE_ATTACHMENT_LOAD_OP_LOAD = 0,
|
SE_ATTACHMENT_LOAD_OP_LOAD = 0,
|
||||||
|
|||||||
@@ -50,73 +50,63 @@ struct ViewportCreateInfo
|
|||||||
// doesnt own the data, only proxy it
|
// doesnt own the data, only proxy it
|
||||||
struct BulkResourceData
|
struct BulkResourceData
|
||||||
{
|
{
|
||||||
uint32 size;
|
uint32 size = 0;
|
||||||
uint8 *data;
|
uint8 *data = nullptr;
|
||||||
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
Gfx::QueueType owner = Gfx::QueueType::GRAPHICS;
|
||||||
BulkResourceData()
|
|
||||||
: size(0), data(nullptr), owner(Gfx::QueueType::GRAPHICS)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct TextureCreateInfo
|
struct TextureCreateInfo
|
||||||
{
|
{
|
||||||
BulkResourceData resourceData;
|
BulkResourceData resourceData = BulkResourceData();
|
||||||
uint32 width;
|
uint32 width = 1;
|
||||||
uint32 height;
|
uint32 height = 1;
|
||||||
uint32 depth;
|
uint32 depth = 1;
|
||||||
bool bArray;
|
bool bArray = false;
|
||||||
uint32 arrayLayers;
|
uint32 arrayLayers = 1;
|
||||||
uint32 mipLevels;
|
uint32 mipLevels = 1;
|
||||||
uint32 samples;
|
uint32 samples = 1;
|
||||||
Gfx::SeFormat format;
|
Gfx::SeFormat format = Gfx::SE_FORMAT_R32G32B32A32_SFLOAT;
|
||||||
Gfx::SeImageUsageFlagBits usage;
|
Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
|
||||||
TextureCreateInfo()
|
|
||||||
: resourceData(), width(1), height(1), depth(1), bArray(false), arrayLayers(1)
|
|
||||||
, mipLevels(1), samples(1), format(Gfx::SE_FORMAT_R32G32B32A32_SFLOAT)
|
|
||||||
, usage(Gfx::SE_IMAGE_USAGE_SAMPLED_BIT)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct SamplerCreateInfo
|
struct SamplerCreateInfo
|
||||||
{
|
{
|
||||||
|
Gfx::SeSamplerCreateFlags flags;
|
||||||
|
Gfx::SeFilter magFilter;
|
||||||
|
Gfx::SeFilter minFilter;
|
||||||
|
Gfx::SeSamplerMipmapMode mipmapMode;
|
||||||
|
Gfx::SeSamplerAddressMode addressModeU;
|
||||||
|
Gfx::SeSamplerAddressMode addressModeV;
|
||||||
|
Gfx::SeSamplerAddressMode addressModeW;
|
||||||
|
float mipLodBias;
|
||||||
|
uint32 anisotropyEnable;
|
||||||
|
float maxAnisotropy;
|
||||||
|
uint32 compareEnable;
|
||||||
|
Gfx::SeCompareOp compareOp;
|
||||||
|
float minLod;
|
||||||
|
float maxLod;
|
||||||
|
Gfx::SeBorderColor borderColor;
|
||||||
|
uint32 unnormalizedCoordinates;
|
||||||
};
|
};
|
||||||
struct VertexBufferCreateInfo
|
struct VertexBufferCreateInfo
|
||||||
{
|
{
|
||||||
BulkResourceData resourceData;
|
BulkResourceData resourceData = BulkResourceData();
|
||||||
// bytes per vertex
|
// bytes per vertex
|
||||||
uint32 vertexSize;
|
uint32 vertexSize = 0;
|
||||||
uint32 numVertices;
|
uint32 numVertices = 0;
|
||||||
VertexBufferCreateInfo()
|
|
||||||
: resourceData(), vertexSize(0), numVertices(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct IndexBufferCreateInfo
|
struct IndexBufferCreateInfo
|
||||||
{
|
{
|
||||||
BulkResourceData resourceData;
|
BulkResourceData resourceData = BulkResourceData();
|
||||||
Gfx::SeIndexType indexType;
|
Gfx::SeIndexType indexType = Gfx::SeIndexType::SE_INDEX_TYPE_UINT16;
|
||||||
IndexBufferCreateInfo()
|
|
||||||
: resourceData(), indexType(Gfx::SeIndexType::SE_INDEX_TYPE_UINT16)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct UniformBufferCreateInfo
|
struct UniformBufferCreateInfo
|
||||||
{
|
{
|
||||||
BulkResourceData resourceData;
|
BulkResourceData resourceData = BulkResourceData();
|
||||||
uint8 bDynamic : 1;
|
uint8 bDynamic : 1 = 0;
|
||||||
UniformBufferCreateInfo()
|
|
||||||
: resourceData(), bDynamic(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct StructuredBufferCreateInfo
|
struct StructuredBufferCreateInfo
|
||||||
{
|
{
|
||||||
BulkResourceData resourceData;
|
BulkResourceData resourceData;
|
||||||
uint8 bDynamic: 1;
|
uint8 bDynamic: 1;
|
||||||
StructuredBufferCreateInfo()
|
|
||||||
: resourceData(), bDynamic(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
struct ShaderCreateInfo
|
struct ShaderCreateInfo
|
||||||
{
|
{
|
||||||
@@ -138,13 +128,6 @@ struct SePushConstantRange
|
|||||||
};
|
};
|
||||||
struct VertexElement
|
struct VertexElement
|
||||||
{
|
{
|
||||||
VertexElement(){}
|
|
||||||
//VertexElement(uint8 attributeIndex, SeFormat vertexFormat, uint8 offset)
|
|
||||||
// : attributeIndex(attributeIndex), vertexFormat(vertexFormat), offset(offset)
|
|
||||||
//{}
|
|
||||||
VertexElement(uint8 streamIndex, uint8 offset, SeFormat vertexFormat, uint8 attributeIndex, uint8 stride)
|
|
||||||
: streamIndex(streamIndex), offset(offset), vertexFormat(vertexFormat), attributeIndex(attributeIndex), stride(stride)
|
|
||||||
{}
|
|
||||||
uint8 streamIndex;
|
uint8 streamIndex;
|
||||||
uint8 offset;
|
uint8 offset;
|
||||||
SeFormat vertexFormat;
|
SeFormat vertexFormat;
|
||||||
@@ -152,6 +135,7 @@ struct VertexElement
|
|||||||
uint8 stride;
|
uint8 stride;
|
||||||
uint8 bInstanced = 0;
|
uint8 bInstanced = 0;
|
||||||
};
|
};
|
||||||
|
static_assert(std::is_aggregate_v<VertexElement>);
|
||||||
struct RasterizationState
|
struct RasterizationState
|
||||||
{
|
{
|
||||||
uint8 depthClampEnable : 1;
|
uint8 depthClampEnable : 1;
|
||||||
|
|||||||
@@ -93,17 +93,17 @@ ShaderCollection& ShaderMap::createShaders(
|
|||||||
|
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
|
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags)
|
||||||
{
|
{
|
||||||
if (descriptorBindings.size() <= bindingIndex)
|
if (descriptorBindings.size() <= bindingIndex)
|
||||||
{
|
{
|
||||||
descriptorBindings.resize(bindingIndex + 1);
|
descriptorBindings.resize(bindingIndex + 1);
|
||||||
}
|
}
|
||||||
DescriptorBinding binding;
|
DescriptorBinding& binding = descriptorBindings[bindingIndex];
|
||||||
binding.binding = bindingIndex;
|
binding.binding = bindingIndex;
|
||||||
binding.descriptorType = type;
|
binding.descriptorType = type;
|
||||||
binding.descriptorCount = arrayCount;
|
binding.descriptorCount = arrayCount;
|
||||||
descriptorBindings[bindingIndex] = binding;
|
binding.bindingFlags = bindingFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
|
||||||
|
|||||||
@@ -160,16 +160,10 @@ public:
|
|||||||
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
|
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
void operator=(const DescriptorBinding &other)
|
|
||||||
{
|
|
||||||
binding = other.binding;
|
|
||||||
descriptorType = other.descriptorType;
|
|
||||||
descriptorCount = other.descriptorCount;
|
|
||||||
shaderStages = other.shaderStages;
|
|
||||||
}
|
|
||||||
uint32_t binding;
|
uint32_t binding;
|
||||||
SeDescriptorType descriptorType;
|
SeDescriptorType descriptorType;
|
||||||
uint32_t descriptorCount;
|
uint32_t descriptorCount;
|
||||||
|
SeDescriptorBindingFlags bindingFlags = 0;
|
||||||
SeShaderStageFlags shaderStages;
|
SeShaderStageFlags shaderStages;
|
||||||
};
|
};
|
||||||
DEFINE_REF(DescriptorBinding)
|
DEFINE_REF(DescriptorBinding)
|
||||||
@@ -196,6 +190,7 @@ public:
|
|||||||
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
|
virtual void updateBuffer(uint32 binding, PStructuredBuffer structuredBuffer) = 0;
|
||||||
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
|
virtual void updateSampler(uint32 binding, PSamplerState samplerState) = 0;
|
||||||
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
|
virtual void updateTexture(uint32 binding, PTexture texture, PSamplerState samplerState = nullptr) = 0;
|
||||||
|
virtual void updateTextureArray(uint32_t binding, Array<PTexture> texture) = 0;
|
||||||
virtual bool operator<(PDescriptorSet other) = 0;
|
virtual bool operator<(PDescriptorSet other) = 0;
|
||||||
|
|
||||||
virtual uint32 getSetIndex() const = 0;
|
virtual uint32 getSetIndex() const = 0;
|
||||||
@@ -224,7 +219,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
virtual void create() = 0;
|
virtual void create() = 0;
|
||||||
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1);
|
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0);
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual PDescriptorSet allocateDescriptorSet();
|
virtual PDescriptorSet allocateDescriptorSet();
|
||||||
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
|
||||||
@@ -557,6 +552,7 @@ public:
|
|||||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
|
||||||
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
|
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) = 0;
|
||||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) = 0;
|
||||||
|
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
|
||||||
virtual void draw(const MeshBatchElement& data) = 0;
|
virtual void draw(const MeshBatchElement& data) = 0;
|
||||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
|
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) = 0;
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -571,6 +567,7 @@ public:
|
|||||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
|
virtual void bindPipeline(Gfx::PComputePipeline pipeline) = 0;
|
||||||
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
|
virtual void bindDescriptor(Gfx::PDescriptorSet set) = 0;
|
||||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) = 0;
|
||||||
|
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) = 0;
|
||||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
|
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) = 0;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,5 +11,7 @@ target_sources(Engine
|
|||||||
RenderGraph.h
|
RenderGraph.h
|
||||||
RenderGraph.cpp
|
RenderGraph.cpp
|
||||||
RenderPass.h
|
RenderPass.h
|
||||||
|
TextPass.h
|
||||||
|
TextPass.cpp
|
||||||
UIPass.h
|
UIPass.h
|
||||||
UIPass.cpp)
|
UIPass.cpp)
|
||||||
@@ -0,0 +1,200 @@
|
|||||||
|
#include "TextPass.h"
|
||||||
|
#include "RenderGraph.h"
|
||||||
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Graphics/VertexShaderInput.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
TextPass::TextPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment attachment)
|
||||||
|
: RenderPass(graphics, viewport)
|
||||||
|
, renderTarget(attachment)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TextPass::~TextPass()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MainJob TextPass::beginFrame()
|
||||||
|
{
|
||||||
|
for(TextRender& render : passData.texts)
|
||||||
|
{
|
||||||
|
FontData& fontData = getFontData(render.font);
|
||||||
|
TextResources& resources = textResources.add();
|
||||||
|
Array<GlyphInstanceData> instanceData;
|
||||||
|
float x = render.position.x;
|
||||||
|
float y = render.position.y;
|
||||||
|
for(uint32 c : render.text)
|
||||||
|
{
|
||||||
|
instanceData.add(GlyphInstanceData{
|
||||||
|
.glyphIndex = fontData.characterToGlyphIndex[c],
|
||||||
|
.position = Vector2(x, y)
|
||||||
|
});
|
||||||
|
x += (fontData.characterAdvance[c] >> 6) * render.scale;
|
||||||
|
}
|
||||||
|
VertexBufferCreateInfo vbInfo;
|
||||||
|
vbInfo.numVertices = static_cast<uint32>(instanceData.size());
|
||||||
|
vbInfo.vertexSize = sizeof(GlyphInstanceData);
|
||||||
|
vbInfo.resourceData.data = reinterpret_cast<uint8*>(instanceData.data());
|
||||||
|
vbInfo.resourceData.size = static_cast<uint32>(instanceData.size());
|
||||||
|
resources.vertexBuffer = graphics->createVertexBuffer(vbInfo);
|
||||||
|
|
||||||
|
resources.descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||||
|
resources.descriptorSet->updateBuffer(0, projectionBuffer);
|
||||||
|
resources.descriptorSet->updateSampler(1, glyphSampler);
|
||||||
|
resources.descriptorSet->updateBuffer(2, fontData.structuredBuffer);
|
||||||
|
resources.descriptorSet->writeChanges();
|
||||||
|
|
||||||
|
resources.textureArraySet = descriptorLayout->allocateDescriptorSet();
|
||||||
|
resources.textureArraySet->updateTextureArray(0, fontData.textures);
|
||||||
|
|
||||||
|
resources.textureArraySet->writeChanges();
|
||||||
|
resources.scale = render.scale;
|
||||||
|
}
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainJob TextPass::render()
|
||||||
|
{
|
||||||
|
graphics->beginRenderPass(renderPass);
|
||||||
|
Array<Gfx::PRenderCommand> commands;
|
||||||
|
for(TextResources& resources : textResources)
|
||||||
|
{
|
||||||
|
Gfx::PRenderCommand command = graphics->createRenderCommand("TextPassCommand");
|
||||||
|
command->setViewport(viewport);
|
||||||
|
command->bindPipeline(pipeline);
|
||||||
|
|
||||||
|
command->bindVertexBuffer({VertexInputStream(0, 0, resources.vertexBuffer)});
|
||||||
|
|
||||||
|
command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &resources.scale);
|
||||||
|
command->draw(4, static_cast<uint32>(resources.vertexBuffer->getNumVertices()), 0, 0);
|
||||||
|
commands.add(command);
|
||||||
|
}
|
||||||
|
graphics->executeCommands(commands);
|
||||||
|
graphics->endRenderPass();
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainJob TextPass::endFrame()
|
||||||
|
{
|
||||||
|
co_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextPass::publishOutputs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextPass::createRenderPass()
|
||||||
|
{
|
||||||
|
depthAttachment = resources->requestRenderTarget("UIPASS_DEPTH");
|
||||||
|
std::ifstream codeStream("./shaders/TextPass.slang", std::ios::ate);
|
||||||
|
auto fileSize = codeStream.tellg();
|
||||||
|
codeStream.seekg(0);
|
||||||
|
Array<char> buffer(static_cast<uint32>(fileSize));
|
||||||
|
codeStream.read(buffer.data(), fileSize);
|
||||||
|
|
||||||
|
ShaderCreateInfo createInfo;
|
||||||
|
createInfo.shaderCode.add(std::string(buffer.data()));
|
||||||
|
createInfo.defines["INDEX_VIEW_PARAMS"] = "0";
|
||||||
|
createInfo.name = "TextVertex";
|
||||||
|
createInfo.entryPoint = "vertexMain";
|
||||||
|
vertexShader = graphics->createVertexShader(createInfo);
|
||||||
|
|
||||||
|
createInfo.name = "TextFragment";
|
||||||
|
createInfo.entryPoint = "fragmentMain";
|
||||||
|
fragmentShader = graphics->createFragmentShader(createInfo);
|
||||||
|
Array<Gfx::VertexElement> elements;
|
||||||
|
elements.add({
|
||||||
|
.streamIndex = 0,
|
||||||
|
.offset = offsetof(GlyphInstanceData, glyphIndex),
|
||||||
|
.vertexFormat = Gfx::SE_FORMAT_R32_UINT,
|
||||||
|
.attributeIndex = 0,
|
||||||
|
.stride = sizeof(GlyphInstanceData),
|
||||||
|
.bInstanced = 1
|
||||||
|
});
|
||||||
|
elements.add({
|
||||||
|
.streamIndex = 0,
|
||||||
|
.offset = offsetof(GlyphInstanceData, position),
|
||||||
|
.vertexFormat = Gfx::SE_FORMAT_R32G32_SFLOAT,
|
||||||
|
.attributeIndex = 1,
|
||||||
|
.stride = sizeof(GlyphInstanceData),
|
||||||
|
.bInstanced = 1
|
||||||
|
});
|
||||||
|
declaration = graphics->createVertexDeclaration(elements);
|
||||||
|
|
||||||
|
descriptorLayout = graphics->createDescriptorLayout("TextDescriptor");
|
||||||
|
descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||||
|
descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
||||||
|
descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, 128, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
|
||||||
|
descriptorLayout->create();
|
||||||
|
|
||||||
|
textureArrayLayout = graphics->createDescriptorLayout("TextureArray");
|
||||||
|
textureArrayLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 128, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT);
|
||||||
|
textureArrayLayout->create();
|
||||||
|
|
||||||
|
Matrix4 projectionMatrix = glm::ortho(0.f, (float)viewport->getSizeX(), 0.f, (float)viewport->getSizeY());
|
||||||
|
projectionBuffer = graphics->createUniformBuffer({
|
||||||
|
.resourceData = {
|
||||||
|
.size = sizeof(Matrix4),
|
||||||
|
.data = (uint8*)&projectionMatrix,
|
||||||
|
},
|
||||||
|
.bDynamic = false,
|
||||||
|
});
|
||||||
|
|
||||||
|
glyphSampler = graphics->createSamplerState({
|
||||||
|
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||||
|
.addressModeU = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
|
||||||
|
.addressModeV = Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE
|
||||||
|
});
|
||||||
|
|
||||||
|
pipelineLayout = graphics->createPipelineLayout();
|
||||||
|
pipelineLayout->addDescriptorLayout(0, descriptorLayout);
|
||||||
|
pipelineLayout->addDescriptorLayout(1, textureArrayLayout);
|
||||||
|
pipelineLayout->addPushConstants({
|
||||||
|
.stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.offset = 0,
|
||||||
|
.size = sizeof(float)});
|
||||||
|
pipelineLayout->create();
|
||||||
|
|
||||||
|
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(renderTarget, depthAttachment);
|
||||||
|
renderPass = graphics->createRenderPass(layout, viewport);
|
||||||
|
|
||||||
|
GraphicsPipelineCreateInfo pipelineInfo;
|
||||||
|
pipelineInfo.vertexDeclaration = declaration;
|
||||||
|
pipelineInfo.vertexShader = vertexShader;
|
||||||
|
pipelineInfo.fragmentShader = fragmentShader;
|
||||||
|
pipelineInfo.renderPass = renderPass;
|
||||||
|
pipelineInfo.pipelineLayout = pipelineLayout;
|
||||||
|
pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE;
|
||||||
|
pipelineInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
|
||||||
|
|
||||||
|
pipeline = graphics->createGraphicsPipeline(pipelineInfo);
|
||||||
|
}
|
||||||
|
TextPass::FontData& TextPass::getFontData(PFontAsset font)
|
||||||
|
{
|
||||||
|
if(fontData.exists(font))
|
||||||
|
{
|
||||||
|
return fontData[font];
|
||||||
|
}
|
||||||
|
const Map<uint32, FontAsset::Glyph>& fontGlyphs = font->getGlyphData();
|
||||||
|
FontData& fd = fontData[font];
|
||||||
|
Array<GlyphData> buffer;
|
||||||
|
buffer.reserve(fontGlyphs.size());
|
||||||
|
for(const auto& [key, value] : fontGlyphs)
|
||||||
|
{
|
||||||
|
fd.characterToGlyphIndex[key] = static_cast<uint32>(buffer.size());
|
||||||
|
fd.characterAdvance[key] = value.advance;
|
||||||
|
fd.textures.add(value.texture);
|
||||||
|
GlyphData& gd = buffer.add();
|
||||||
|
gd.bearing = value.bearing;
|
||||||
|
gd.size = value.size;
|
||||||
|
}
|
||||||
|
StructuredBufferCreateInfo bufferInfo;
|
||||||
|
bufferInfo.bDynamic = false;
|
||||||
|
bufferInfo.resourceData.data = reinterpret_cast<uint8*>(buffer.data());
|
||||||
|
bufferInfo.resourceData.size = static_cast<uint32>(buffer.size());
|
||||||
|
fd.structuredBuffer = graphics->createStructuredBuffer(bufferInfo);
|
||||||
|
return fontData[font];
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "RenderPass.h"
|
||||||
|
#include "UI/RenderHierarchy.h"
|
||||||
|
#include "Graphics/GraphicsResources.h"
|
||||||
|
#include "Asset/FontAsset.h"
|
||||||
|
|
||||||
|
namespace Seele
|
||||||
|
{
|
||||||
|
DECLARE_NAME_REF(Gfx, Texture2D)
|
||||||
|
DECLARE_NAME_REF(Gfx, RenderTargetAttachment)
|
||||||
|
DECLARE_NAME_REF(Gfx, StructuredBuffer)
|
||||||
|
struct TextRender
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
PFontAsset font;
|
||||||
|
Vector4 textColor;
|
||||||
|
Vector2 position;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
struct TextPassData
|
||||||
|
{
|
||||||
|
Array<TextRender> texts;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TextPass : public RenderPass<TextPassData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextPass(Gfx::PGraphics graphics, Gfx::PViewport viewport, Gfx::PRenderTargetAttachment renderTarget);
|
||||||
|
virtual ~TextPass();
|
||||||
|
virtual MainJob beginFrame() override;
|
||||||
|
virtual MainJob render() override;
|
||||||
|
virtual MainJob endFrame() override;
|
||||||
|
virtual void publishOutputs() override;
|
||||||
|
virtual void createRenderPass() override;
|
||||||
|
private:
|
||||||
|
struct GlyphData
|
||||||
|
{
|
||||||
|
Vector2 bearing;
|
||||||
|
Vector2 size;
|
||||||
|
};
|
||||||
|
struct GlyphInstanceData
|
||||||
|
{
|
||||||
|
uint32 glyphIndex;
|
||||||
|
Vector2 position;
|
||||||
|
};
|
||||||
|
struct FontData
|
||||||
|
{
|
||||||
|
Gfx::PStructuredBuffer structuredBuffer;
|
||||||
|
Array<Gfx::PTexture> textures;
|
||||||
|
Map<uint32, uint32> characterToGlyphIndex;
|
||||||
|
// Logically this should be part of GlyphData,
|
||||||
|
// but because GlyphData mirrors shader data and we need
|
||||||
|
// the advance on the CPU, we need this in a separate structure
|
||||||
|
Map<uint32, uint32> characterAdvance;
|
||||||
|
};
|
||||||
|
FontData& getFontData(PFontAsset font);
|
||||||
|
Map<PFontAsset, FontData> fontData;
|
||||||
|
|
||||||
|
struct TextResources
|
||||||
|
{
|
||||||
|
Gfx::PDescriptorSet descriptorSet;
|
||||||
|
Gfx::PDescriptorSet textureArraySet;
|
||||||
|
Gfx::PVertexBuffer vertexBuffer;
|
||||||
|
float scale;
|
||||||
|
};
|
||||||
|
Array<TextResources> textResources;
|
||||||
|
|
||||||
|
Gfx::PRenderTargetAttachment renderTarget;
|
||||||
|
Gfx::PRenderTargetAttachment depthAttachment;
|
||||||
|
Gfx::PTexture2D depthBuffer;
|
||||||
|
|
||||||
|
Gfx::PDescriptorLayout descriptorLayout;
|
||||||
|
Gfx::PDescriptorLayout textureArrayLayout;
|
||||||
|
|
||||||
|
Gfx::PUniformBuffer projectionBuffer;
|
||||||
|
Gfx::PSamplerState glyphSampler;
|
||||||
|
|
||||||
|
Gfx::PVertexDeclaration declaration;
|
||||||
|
Gfx::PVertexShader vertexShader;
|
||||||
|
Gfx::PFragmentShader fragmentShader;
|
||||||
|
Gfx::PPipelineLayout pipelineLayout;
|
||||||
|
Gfx::PGraphicsPipeline pipeline;
|
||||||
|
};
|
||||||
|
DEFINE_REF(TextPass);
|
||||||
|
} // namespace Seele
|
||||||
@@ -290,6 +290,13 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
|
|||||||
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
|
||||||
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
|
||||||
|
{
|
||||||
|
assert(threadId == std::this_thread::get_id());
|
||||||
|
vkCmdPushConstants(handle, layout.cast<PipelineLayout>()->getHandle(), stage, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
void RenderCommand::draw(const MeshBatchElement& data)
|
void RenderCommand::draw(const MeshBatchElement& data)
|
||||||
{
|
{
|
||||||
assert(threadId == std::this_thread::get_id());
|
assert(threadId == std::this_thread::get_id());
|
||||||
@@ -386,6 +393,12 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
|
|||||||
delete[] sets;
|
delete[] sets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ComputeCommand::pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
|
||||||
|
{
|
||||||
|
assert(threadId == std::this_thread::get_id());
|
||||||
|
vkCmdPushConstants(handle, layout.cast<PipelineLayout>()->getHandle(), stage, offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
||||||
{
|
{
|
||||||
assert(threadId == std::this_thread::get_id());
|
assert(threadId == std::this_thread::get_id());
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public:
|
|||||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
|
||||||
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override;
|
virtual void bindVertexBuffer(const Array<VertexInputStream>& streams) override;
|
||||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||||
|
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||||
virtual void draw(const MeshBatchElement& data) override;
|
virtual void draw(const MeshBatchElement& data) override;
|
||||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||||
private:
|
private:
|
||||||
@@ -121,6 +122,7 @@ public:
|
|||||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||||
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
|
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
|
||||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
|
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
|
||||||
|
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
|
||||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||||
private:
|
private:
|
||||||
PComputePipeline pipeline;
|
PComputePipeline pipeline;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void DescriptorLayout::create()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bindings.resize(descriptorBindings.size());
|
bindings.resize(descriptorBindings.size());
|
||||||
|
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
|
||||||
for (size_t i = 0; i < descriptorBindings.size(); ++i)
|
for (size_t i = 0; i < descriptorBindings.size(); ++i)
|
||||||
{
|
{
|
||||||
VkDescriptorSetLayoutBinding &binding = bindings[i];
|
VkDescriptorSetLayoutBinding &binding = bindings[i];
|
||||||
@@ -38,9 +39,16 @@ void DescriptorLayout::create()
|
|||||||
binding.descriptorType = cast(rhiBinding.descriptorType);
|
binding.descriptorType = cast(rhiBinding.descriptorType);
|
||||||
binding.stageFlags = rhiBinding.shaderStages;
|
binding.stageFlags = rhiBinding.shaderStages;
|
||||||
binding.pImmutableSamplers = nullptr;
|
binding.pImmutableSamplers = nullptr;
|
||||||
|
bindingFlags[i] = rhiBinding.bindingFlags;
|
||||||
}
|
}
|
||||||
VkDescriptorSetLayoutCreateInfo createInfo =
|
VkDescriptorSetLayoutCreateInfo createInfo =
|
||||||
init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size());
|
init::DescriptorSetLayoutCreateInfo(bindings.data(), (uint32)bindings.size());
|
||||||
|
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {};
|
||||||
|
bindingFlagsInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO;
|
||||||
|
bindingFlagsInfo.pNext = nullptr;
|
||||||
|
bindingFlagsInfo.bindingCount = static_cast<uint32>(bindingFlags.size());
|
||||||
|
bindingFlagsInfo.pBindingFlags = bindingFlags.data();
|
||||||
|
createInfo.pNext = &bindingFlagsInfo;
|
||||||
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
|
||||||
|
|
||||||
allocator = new DescriptorAllocator(graphics, *this);
|
allocator = new DescriptorAllocator(graphics, *this);
|
||||||
@@ -188,20 +196,54 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
|||||||
imageInfo.sampler = vulkanSampler->sampler;
|
imageInfo.sampler = vulkanSampler->sampler;
|
||||||
}
|
}
|
||||||
imageInfos.add(imageInfo);
|
imageInfos.add(imageInfo);
|
||||||
|
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
if(samplerState != nullptr)
|
||||||
|
{
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
|
}
|
||||||
|
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
|
||||||
|
{
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
}
|
||||||
VkWriteDescriptorSet writeDescriptor =
|
VkWriteDescriptorSet writeDescriptor =
|
||||||
init::WriteDescriptorSet(
|
init::WriteDescriptorSet(
|
||||||
setHandle,
|
setHandle,
|
||||||
samplerState != nullptr ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
descriptorType,
|
||||||
binding,
|
binding,
|
||||||
&imageInfos.back());
|
&imageInfos.back());
|
||||||
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
|
|
||||||
{
|
|
||||||
writeDescriptor.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
|
||||||
}
|
|
||||||
writeDescriptors.add(writeDescriptor);
|
writeDescriptors.add(writeDescriptor);
|
||||||
|
|
||||||
cachedData[binding] = vulkanTexture;
|
cachedData[binding] = vulkanTexture;
|
||||||
}
|
}
|
||||||
|
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures)
|
||||||
|
{
|
||||||
|
// maybe make this a parameter?
|
||||||
|
uint32 arrayElement = 0;
|
||||||
|
for(const auto& gfxTexture : textures)
|
||||||
|
{
|
||||||
|
TextureHandle* vulkanTexture = TextureBase::cast(gfxTexture);
|
||||||
|
imageInfos.add(
|
||||||
|
init::DescriptorImageInfo(
|
||||||
|
VK_NULL_HANDLE,
|
||||||
|
vulkanTexture->getView(),
|
||||||
|
cast(vulkanTexture->getLayout())));
|
||||||
|
|
||||||
|
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
|
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
|
||||||
|
{
|
||||||
|
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||||
|
}
|
||||||
|
VkWriteDescriptorSet& write = writeDescriptors.add(
|
||||||
|
init::WriteDescriptorSet(
|
||||||
|
setHandle,
|
||||||
|
descriptorType,
|
||||||
|
binding,
|
||||||
|
&imageInfos.back()
|
||||||
|
));
|
||||||
|
write.dstArrayElement = arrayElement++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
|
||||||
{
|
{
|
||||||
@@ -281,6 +323,20 @@ void DescriptorAllocator::allocateDescriptorSet(Gfx::PDescriptorSet &descriptorS
|
|||||||
VkDescriptorSetLayout layoutHandle = layout.getHandle();
|
VkDescriptorSetLayout layoutHandle = layout.getHandle();
|
||||||
VkDescriptorSetAllocateInfo allocInfo =
|
VkDescriptorSetAllocateInfo allocInfo =
|
||||||
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
|
init::DescriptorSetAllocateInfo(poolHandle, &layoutHandle, 1);
|
||||||
|
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {};
|
||||||
|
setCounts.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO;
|
||||||
|
setCounts.pNext = nullptr;
|
||||||
|
setCounts.descriptorSetCount = 1;
|
||||||
|
uint32 counts = 0;
|
||||||
|
for(const auto& binding : layout.bindings)
|
||||||
|
{
|
||||||
|
if(binding.binding & Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT)
|
||||||
|
{
|
||||||
|
counts = binding.descriptorCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCounts.pDescriptorCounts = &counts;
|
||||||
|
allocInfo.pNext = &setCounts;
|
||||||
|
|
||||||
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
|
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,11 +12,10 @@ public:
|
|||||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||||
virtual ~DescriptorLayout();
|
virtual ~DescriptorLayout();
|
||||||
virtual void create();
|
virtual void create();
|
||||||
inline VkDescriptorSetLayout getHandle() const
|
constexpr VkDescriptorSetLayout getHandle() const
|
||||||
{
|
{
|
||||||
return layoutHandle;
|
return layoutHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 hash;
|
uint32 hash;
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
@@ -72,6 +71,7 @@ public:
|
|||||||
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
|
virtual void updateBuffer(uint32_t binding, Gfx::PStructuredBuffer uniformBuffer);
|
||||||
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
|
virtual void updateSampler(uint32_t binding, Gfx::PSamplerState samplerState);
|
||||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
|
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSamplerState sampler = nullptr);
|
||||||
|
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture);
|
||||||
virtual bool operator<(Gfx::PDescriptorSet other);
|
virtual bool operator<(Gfx::PDescriptorSet other);
|
||||||
|
|
||||||
inline bool isCurrentlyBound() const
|
inline bool isCurrentlyBound() const
|
||||||
|
|||||||
@@ -204,11 +204,27 @@ Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreat
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo&)
|
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation
|
PSamplerState sampler = new SamplerState();
|
||||||
VkSamplerCreateInfo vkInfo =
|
VkSamplerCreateInfo vkInfo =
|
||||||
init::SamplerCreateInfo();
|
init::SamplerCreateInfo();
|
||||||
|
vkInfo.addressModeU = cast(createInfo.addressModeU);
|
||||||
|
vkInfo.addressModeV = cast(createInfo.addressModeV);
|
||||||
|
vkInfo.addressModeW = cast(createInfo.addressModeW);
|
||||||
|
vkInfo.anisotropyEnable = createInfo.anisotropyEnable;
|
||||||
|
vkInfo.borderColor = cast(createInfo.borderColor);
|
||||||
|
vkInfo.compareEnable = createInfo.compareEnable;
|
||||||
|
vkInfo.compareOp = cast(createInfo.compareOp);
|
||||||
|
vkInfo.flags = createInfo.flags;
|
||||||
|
vkInfo.magFilter = cast(createInfo.magFilter);
|
||||||
|
vkInfo.maxAnisotropy = createInfo.maxAnisotropy;
|
||||||
|
vkInfo.maxLod = createInfo.maxLod;
|
||||||
|
vkInfo.minFilter = cast(createInfo.minFilter);
|
||||||
|
vkInfo.minLod = createInfo.minLod;
|
||||||
|
vkInfo.mipLodBias = createInfo.mipLodBias;
|
||||||
|
vkInfo.mipmapMode = cast(createInfo.mipmapMode);
|
||||||
|
vkInfo.unnormalizedCoordinates = createInfo.unnormalizedCoordinates;
|
||||||
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
|
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
@@ -537,6 +553,15 @@ void Graphics::createDevice(GraphicsInitializer initializer)
|
|||||||
queueInfos.data(),
|
queueInfos.data(),
|
||||||
(uint32)queueInfos.size(),
|
(uint32)queueInfos.size(),
|
||||||
&features);
|
&features);
|
||||||
|
|
||||||
|
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {};
|
||||||
|
std::memset(&descriptorIndexing, 0, sizeof(descriptorIndexing));
|
||||||
|
descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
|
||||||
|
descriptorIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
|
||||||
|
descriptorIndexing.runtimeDescriptorArray = VK_TRUE;
|
||||||
|
descriptorIndexing.descriptorBindingVariableDescriptorCount = VK_TRUE;
|
||||||
|
descriptorIndexing.descriptorBindingPartiallyBound = VK_TRUE;
|
||||||
|
deviceInfo.pNext = &descriptorIndexing;
|
||||||
#if ENABLE_VALIDATION
|
#if ENABLE_VALIDATION
|
||||||
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
|
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
|
||||||
crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV;
|
crashDiagInfo.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV;
|
||||||
|
|||||||
@@ -1421,3 +1421,134 @@ Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear)
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode &mode)
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||||
|
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
|
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||||
|
default:
|
||||||
|
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode)
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_REPEAT;
|
||||||
|
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
|
||||||
|
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
|
||||||
|
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
||||||
|
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
|
||||||
|
default:
|
||||||
|
return SE_SAMPLER_ADDRESS_MODE_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color)
|
||||||
|
{
|
||||||
|
switch(color)
|
||||||
|
{
|
||||||
|
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||||
|
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||||
|
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||||
|
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
|
||||||
|
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||||
|
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||||
|
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||||
|
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||||
|
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||||
|
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||||
|
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||||
|
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
|
||||||
|
default:
|
||||||
|
return VK_BORDER_COLOR_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color)
|
||||||
|
{
|
||||||
|
switch(color)
|
||||||
|
{
|
||||||
|
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
||||||
|
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
||||||
|
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
||||||
|
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
|
||||||
|
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
||||||
|
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
|
||||||
|
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
|
||||||
|
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
|
||||||
|
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
||||||
|
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
|
||||||
|
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
|
||||||
|
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
|
||||||
|
default:
|
||||||
|
return SE_BORDER_COLOR_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter)
|
||||||
|
{
|
||||||
|
switch(filter)
|
||||||
|
{
|
||||||
|
case SE_FILTER_NEAREST:
|
||||||
|
return VK_FILTER_NEAREST;
|
||||||
|
case SE_FILTER_LINEAR:
|
||||||
|
return VK_FILTER_LINEAR;
|
||||||
|
case SE_FILTER_CUBIC_IMG:
|
||||||
|
return VK_FILTER_CUBIC_IMG;
|
||||||
|
default:
|
||||||
|
return VK_FILTER_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
|
||||||
|
{
|
||||||
|
switch(filter)
|
||||||
|
{
|
||||||
|
case VK_FILTER_NEAREST:
|
||||||
|
return SE_FILTER_NEAREST;
|
||||||
|
case VK_FILTER_LINEAR:
|
||||||
|
return SE_FILTER_LINEAR;
|
||||||
|
case VK_FILTER_CUBIC_IMG:
|
||||||
|
return SE_FILTER_CUBIC_IMG;
|
||||||
|
default:
|
||||||
|
return SE_FILTER_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter)
|
||||||
|
{
|
||||||
|
switch(filter)
|
||||||
|
{
|
||||||
|
case SE_SAMPLER_MIPMAP_MODE_NEAREST:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case SE_SAMPLER_MIPMAP_MODE_LINEAR:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
default:
|
||||||
|
return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
|
||||||
|
{
|
||||||
|
switch(filter)
|
||||||
|
{
|
||||||
|
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
|
||||||
|
return SE_SAMPLER_MIPMAP_MODE_NEAREST;
|
||||||
|
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
|
||||||
|
return SE_SAMPLER_MIPMAP_MODE_LINEAR;
|
||||||
|
default:
|
||||||
|
return SE_SAMPLER_MIPMAP_MODE_MAX_ENUM;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -54,5 +54,13 @@ VkCompareOp cast(const Gfx::SeCompareOp &op);
|
|||||||
Gfx::SeCompareOp cast(const VkCompareOp &op);
|
Gfx::SeCompareOp cast(const VkCompareOp &op);
|
||||||
VkClearValue cast(const Gfx::SeClearValue &clear);
|
VkClearValue cast(const Gfx::SeClearValue &clear);
|
||||||
Gfx::SeClearValue cast(const VkClearValue &clear);
|
Gfx::SeClearValue cast(const VkClearValue &clear);
|
||||||
|
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode &mode);
|
||||||
|
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode &mode);
|
||||||
|
VkBorderColor cast(const Gfx::SeBorderColor &color);
|
||||||
|
Gfx::SeBorderColor cast(const VkBorderColor &color);
|
||||||
|
VkFilter cast(const Gfx::SeFilter &filter);
|
||||||
|
Gfx::SeFilter cast(const VkFilter &filter);
|
||||||
|
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode &filter);
|
||||||
|
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode &filter);
|
||||||
} // namespace Vulkan
|
} // namespace Vulkan
|
||||||
} // namespace Seele
|
} // namespace Seele
|
||||||
@@ -116,8 +116,7 @@ void MaterialAsset::load()
|
|||||||
{
|
{
|
||||||
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
|
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
|
||||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
||||||
SamplerCreateInfo createInfo;
|
p->data = WindowManager::getGraphics()->createSamplerState({});
|
||||||
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
|
|
||||||
parameters.add(p);
|
parameters.add(p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -2,17 +2,29 @@
|
|||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Scene/Actor/Actor.h"
|
#include "Scene/Actor/Actor.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Asset/AssetRegistry.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
|
|
||||||
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo)
|
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo)
|
||||||
: View(graphics, window, createInfo, "InspectorView")
|
: View(graphics, window, createInfo, "InspectorView")
|
||||||
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
|
, uiPass(UIPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
|
||||||
|
, textPass(TextPass(graphics, viewport, new Gfx::SwapchainAttachment(window->getGfxHandle())))
|
||||||
{
|
{
|
||||||
|
AssetRegistry::importFile("./fonts/Calibri.ttf");
|
||||||
PRenderGraphResources resources = new RenderGraphResources();
|
PRenderGraphResources resources = new RenderGraphResources();
|
||||||
uiPass.setResources(resources);
|
uiPass.setResources(resources);
|
||||||
|
textPass.setResources(resources);
|
||||||
uiPass.publishOutputs();
|
uiPass.publishOutputs();
|
||||||
|
textPass.publishOutputs();
|
||||||
uiPass.createRenderPass();
|
uiPass.createRenderPass();
|
||||||
|
textPass.createRenderPass();
|
||||||
|
TextRender& render = textPassData.texts.add();
|
||||||
|
render.font = AssetRegistry::findFont("Calibri");
|
||||||
|
render.text = "Seele Engine";
|
||||||
|
render.position = Vector2(0.5f, 0.5f);
|
||||||
|
render.scale = 1.0f;
|
||||||
|
render.textColor = Vector4(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorView::~InspectorView()
|
InspectorView::~InspectorView()
|
||||||
@@ -31,19 +43,21 @@ Job InspectorView::update()
|
|||||||
|
|
||||||
void InspectorView::commitUpdate()
|
void InspectorView::commitUpdate()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorView::prepareRender()
|
void InspectorView::prepareRender()
|
||||||
{
|
{
|
||||||
|
textPass.updateViewFrame(textPassData);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainJob InspectorView::render()
|
MainJob InspectorView::render()
|
||||||
{
|
{
|
||||||
return uiPass.beginFrame()
|
return uiPass.beginFrame()
|
||||||
|
.then(textPass.beginFrame())
|
||||||
.then(uiPass.render())
|
.then(uiPass.render())
|
||||||
.then(uiPass.endFrame());
|
.then(textPass.render())
|
||||||
|
.then(uiPass.endFrame())
|
||||||
|
.then(textPass.endFrame());
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
|
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "View.h"
|
#include "View.h"
|
||||||
#include "Graphics/RenderPass/RenderGraph.h"
|
#include "Graphics/RenderPass/RenderGraph.h"
|
||||||
#include "Graphics/RenderPass/UIPass.h"
|
#include "Graphics/RenderPass/UIPass.h"
|
||||||
|
#include "Graphics/RenderPass/TextPass.h"
|
||||||
#include "UI/Elements/Panel.h"
|
#include "UI/Elements/Panel.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
@@ -22,8 +23,10 @@ public:
|
|||||||
void selectActor();
|
void selectActor();
|
||||||
protected:
|
protected:
|
||||||
UIPass uiPass;
|
UIPass uiPass;
|
||||||
|
TextPass textPass;
|
||||||
|
|
||||||
UIPassData uiPassData;
|
UIPassData uiPassData;
|
||||||
|
TextPassData textPassData;
|
||||||
|
|
||||||
UI::PPanel rootPanel;
|
UI::PPanel rootPanel;
|
||||||
PActor selectedActor;
|
PActor selectedActor;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const Viewpo
|
|||||||
{
|
{
|
||||||
scene = new Scene(graphics);
|
scene = new Scene(graphics);
|
||||||
scene->addActor(activeCamera);
|
scene->addActor(activeCamera);
|
||||||
AssetRegistry::importFile("./fonts/GLSNECB.ttf");
|
|
||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Diffuse.png");
|
||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Body_Lightmap.png");
|
||||||
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
|
AssetRegistry::importFile("C:\\Users\\Dynamitos\\TestSeeleProject\\Assets\\Ayaka\\Avatar_Girl_Sword_Ayaka_Tex_Face_Diffuse.png");
|
||||||
|
|||||||
+4
-136
@@ -19,7 +19,7 @@ int main()
|
|||||||
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_B8G8R8A8_UNORM;
|
||||||
auto window = windowManager->addWindow(mainWindowInfo);
|
auto window = windowManager->addWindow(mainWindowInfo);
|
||||||
ViewportCreateInfo sceneViewInfo;
|
ViewportCreateInfo sceneViewInfo;
|
||||||
sceneViewInfo.sizeX = 1280;
|
sceneViewInfo.sizeX = 680;
|
||||||
sceneViewInfo.sizeY = 720;
|
sceneViewInfo.sizeY = 720;
|
||||||
sceneViewInfo.offsetX = 0;
|
sceneViewInfo.offsetX = 0;
|
||||||
sceneViewInfo.offsetY = 0;
|
sceneViewInfo.offsetY = 0;
|
||||||
@@ -31,144 +31,12 @@ int main()
|
|||||||
inspectorViewInfo.sizeY = 720;
|
inspectorViewInfo.sizeY = 720;
|
||||||
inspectorViewInfo.offsetX = 640;
|
inspectorViewInfo.offsetX = 640;
|
||||||
inspectorViewInfo.offsetY = 0;
|
inspectorViewInfo.offsetY = 0;
|
||||||
//PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
PInspectorView inspectorView = new InspectorView(windowManager->getGraphics(), window, inspectorViewInfo);
|
||||||
//window->addView(inspectorView);
|
window->addView(inspectorView);
|
||||||
sceneView->setFocused();
|
sceneView->setFocused();
|
||||||
|
|
||||||
window->render();
|
window->render();
|
||||||
|
|
||||||
getGlobalThreadPool().mainLoop();
|
getGlobalThreadPool().mainLoop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
#include <coroutine>
|
|
||||||
#include <iostream>
|
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
struct Return;
|
|
||||||
struct Promise
|
|
||||||
{
|
|
||||||
Promise()
|
|
||||||
{
|
|
||||||
handle = std::coroutine_handle<Promise>::from_promise(*this);
|
|
||||||
numRefs = 0;
|
|
||||||
}
|
|
||||||
Return get_return_object();
|
|
||||||
std::suspend_always initial_suspend() noexcept { return {}; }
|
|
||||||
std::suspend_always final_suspend() noexcept { return {}; }
|
|
||||||
void return_void() {}
|
|
||||||
void unhandled_exception() {}
|
|
||||||
void resume() { handle.resume(); }
|
|
||||||
void addRef()
|
|
||||||
{
|
|
||||||
numRefs++;
|
|
||||||
}
|
|
||||||
void removeRef()
|
|
||||||
{
|
|
||||||
numRefs--;
|
|
||||||
if(numRefs == 0)
|
|
||||||
{
|
|
||||||
if(handle.done())
|
|
||||||
{
|
|
||||||
handle.destroy();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::coroutine_handle<Promise> handle;
|
|
||||||
uint64_t numRefs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Return
|
|
||||||
{
|
|
||||||
using promise_type = Promise;
|
|
||||||
Return(Promise* promise)
|
|
||||||
: promise(promise)
|
|
||||||
{
|
|
||||||
promise->addRef();
|
|
||||||
}
|
|
||||||
Return(const Return& other)
|
|
||||||
{
|
|
||||||
promise = other.promise;
|
|
||||||
if(promise != nullptr)
|
|
||||||
{
|
|
||||||
promise->addRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Return(Return&& other)
|
|
||||||
{
|
|
||||||
promise = other.promise;
|
|
||||||
other.promise = nullptr;
|
|
||||||
}
|
|
||||||
~Return()
|
|
||||||
{
|
|
||||||
promise->removeRef();
|
|
||||||
}
|
|
||||||
Return& operator=(const Return& other)
|
|
||||||
{
|
|
||||||
if(this != &other)
|
|
||||||
{
|
|
||||||
if(promise != nullptr)
|
|
||||||
{
|
|
||||||
promise->removeRef();
|
|
||||||
}
|
|
||||||
promise = other.promise;
|
|
||||||
if(promise != nullptr)
|
|
||||||
{
|
|
||||||
promise->addRef();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
Return& operator=(Return&& other)
|
|
||||||
{
|
|
||||||
if(this != &other)
|
|
||||||
{
|
|
||||||
if(promise != nullptr)
|
|
||||||
{
|
|
||||||
promise->removeRef();
|
|
||||||
}
|
|
||||||
promise = other.promise;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Promise* promise;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
Return Promise::get_return_object(){
|
|
||||||
return {this};
|
|
||||||
}
|
|
||||||
|
|
||||||
Return coro1()
|
|
||||||
{
|
|
||||||
std::cout << "coro1" << std::endl;
|
|
||||||
co_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Return coro2()
|
|
||||||
{
|
|
||||||
std::cout << "coro2" << std::endl;
|
|
||||||
co_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Return coroAll(std::vector<Return> coros)
|
|
||||||
{
|
|
||||||
for(auto coro : coros)
|
|
||||||
{
|
|
||||||
coro.promise->resume();
|
|
||||||
}
|
|
||||||
co_return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
std::vector<Return> returns{coro1(), coro2()};
|
|
||||||
std::thread t = std::thread([returns](){
|
|
||||||
coroAll(returns);
|
|
||||||
});
|
|
||||||
t.join();
|
|
||||||
}*/
|
|
||||||
Reference in New Issue
Block a user