50 Commits

Author SHA1 Message Date
6c7f9ea9d1 perpare it for VertexColor3D material. 2023-09-27 20:31:46 +08:00
253d113375 adjusted path of examples. 2023-09-27 11:36:39 +08:00
ca1bb80b5f updated M_RectTexture2DArray.cpp 2023-09-26 21:57:03 +08:00
922fc2661b added primitive in Material2DCreateConfig 2023-09-26 21:49:37 +08:00
e9a8e5bbf2 updated texture_quad.cpp 2023-09-26 21:16:00 +08:00
bba00534ba removed DescriptorSetType::MaterialInstance 2023-09-26 14:50:38 +08:00
c15fbf8252 texture_rect_array was run OK! 2023-09-25 21:49:35 +08:00
9a7e711658 LoadTexture2DToArray OK! test ok! 2023-09-25 20:32:12 +08:00
65c3d5cad1 renamed to CreateTexture from GetTexture in TextureLoader<> 2023-09-25 19:49:06 +08:00
7d9192051a added codes about Texture2DArray. 2023-09-25 17:34:36 +08:00
22099b6b84 added CopyBufferToImage2D and use it. 2023-09-25 17:33:59 +08:00
322d24c4ca added GPUDevice::CreateTexture2DArray functions. 2023-09-25 17:01:21 +08:00
5230fbc27f added little codes of texture 2d array, but can't run. 2023-09-25 16:38:02 +08:00
f901708b6c improved codes. 2023-09-25 15:37:41 +08:00
2487cb1f36 added CopyBufferToImage.h 2023-09-25 15:13:30 +08:00
7805494ca9 created a new GPUDevice::CopyBufferToImage(CopyBufferToImageInfo *,..) 2023-09-25 14:44:53 +08:00
ac4c97d33a renamed to CopyBufferToImage from CommitTexture 2023-09-25 12:42:48 +08:00
a87a35b5f8 removed old examples. 2023-09-22 11:32:26 +08:00
d456c2bf92 used DescriptorSetType::MaterialInstance 2023-09-22 01:31:04 +08:00
12e18b517b added MaterialInstance::WriteMIData<>(const T &) 2023-09-22 01:30:44 +08:00
2f00aa8e1e improved codes. 2023-09-22 01:08:32 +08:00
4e144072e4 texture_rect run ok! 2023-09-21 22:11:20 +08:00
907cb3c852 added M_RectTexture2D.cpp 2023-09-21 21:36:55 +08:00
eb51df8dd0 Added few codes of ShaderCreateInfoGeometry 2023-09-21 21:36:37 +08:00
ed9ba3876f added PureTexture2D material and test. 2023-09-21 20:46:08 +08:00
97290ce54c fixed a bug that lost a ; in ShaderCreateInfo::ProcSampler() 2023-09-21 20:45:34 +08:00
bebac2284f used FAN instead of TRIANGLES in texture_quad.cpp 2023-09-21 17:38:02 +08:00
d5d6a6bc74 added example that it's texture_quad.cpp. 2023-09-21 17:15:36 +08:00
5559178e7c fixed a bug about RenderablePrimitiveCreater::SetIBO 2023-09-21 17:15:12 +08:00
f58ce4f98b removed dirty codes 2023-09-21 17:14:49 +08:00
5c2f136689 renamed project's name 2023-09-21 10:09:31 +08:00
6820ee8c74 completed AutoMergeMaterialInstance,test ok. next step is to support texture2d array 2023-09-20 21:53:30 +08:00
ddb5a0b77a use VIL instead of MI in to sort for RenderNode 2023-09-20 18:56:09 +08:00
69646971ce used VIL instead of MI in MaterialRenderList 2023-09-20 17:19:46 +08:00
e71ec4be85 Added few RenderPass::CreatePipeline functions. 2023-09-20 17:15:13 +08:00
dbe2370a44 1.used uvec2/ushort2 in AssignVBO
2.completed first step then merge MI buffer
2023-09-20 15:55:14 +08:00
00d2677066 update RenderAssignBuffer,but can't run. 2023-09-19 22:04:34 +08:00
4208e47534 newly material instance stat,but can't run. 2023-09-19 21:45:54 +08:00
2dedeaad90 layouted codes of VKMaterialInstance.h 2023-09-19 21:45:28 +08:00
083600a95f added mi_max_count in Material 2023-09-19 21:44:48 +08:00
902dc20340 used ActiveMemoryBlockManager to manage data of material instances in Material class. 2023-09-19 21:09:09 +08:00
164498446a fixed crash in RenderAssignBuffer.cpp because not check ubo_mi before use. 2023-09-19 21:07:07 +08:00
cef5ad073b a few update 2023-09-07 18:09:31 +08:00
c2279c553d fixed a spell error in word. 2023-09-06 17:06:12 +08:00
d959e7988d moved few values to VKRenderAssign.h 2023-09-06 16:55:04 +08:00
202bff5870 moved few codes to RenderAssignBuffer.cpp from MaterialRenderList.cpp 2023-09-06 16:24:05 +08:00
8437d8d561 named values and macro about RenderAssignBuffer 2023-09-06 15:57:52 +08:00
714fc3dcb7 use hgl_min in MaterialCreateInfo.cpp 2023-09-05 23:36:59 +08:00
e030738a5f removed old codes of L2W in AssignBuffer 2023-09-05 20:52:55 +08:00
28b2b53d03 renamed to RenderAssignBuffer from RenderExtraBuffer 2023-09-05 20:48:47 +08:00
81 changed files with 2098 additions and 965 deletions

2
CMCore

Submodule CMCore updated: 6a21b387f5...416e96c169

2
CMUtil

Submodule CMUtil updated: ff819d8a60...c0990c52eb

View File

@@ -0,0 +1,16 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Basic")
endmacro()
CreateProject(01_draw_triangle_in_NDC draw_triangle_in_NDC.cpp)
CreateProject(02_draw_triangle_use_UBO draw_triangle_use_UBO.cpp)
CreateProject(03_auto_instance auto_instance.cpp)
CreateProject(04_auto_merge_material_instance auto_merge_material_instance.cpp)

View File

@@ -1,5 +1,4 @@
// third_triangle
// 该范例主要演示使用场景树系统绘制多个三角形并利用RenderList进行排序以及自动合并进行Instance渲染
// 该范例主要演示使用RenderList系统绘制多个三角形并利用RenderList进行排序以及自动合并进行Instance渲染
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
@@ -47,7 +46,7 @@ private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D");
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D",Prim::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=true;

View File

@@ -1,5 +1,4 @@
// fourth_triangle
// 该范例主要演示使用材质实例传递颜色参数绘制三角形
// 该范例主要演示使用一个材质下的不同材质实例传递颜色参数绘制三角形并依赖RenderList中的自动合并功能让同一材质下所有不同材质实例的对象一次渲染完成。
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
@@ -7,6 +6,7 @@
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
#include<hgl/color/Color.h>
using namespace hgl;
using namespace hgl::graph;
@@ -23,15 +23,7 @@ constexpr float position_data[VERTEX_COUNT*2]=
0.1, 0.9
};
constexpr float color_data[6][4]=
{
{1,0,0,1},
{1,1,0,1},
{0,1,0,1},
{0,1,1,1},
{0,0,1,1},
{1,0,1,1},
};
constexpr uint DRAW_OBJECT_COUNT=12;
class TestApp:public VulkanApplicationFramework
{
@@ -40,8 +32,13 @@ private:
SceneNode render_root;
RenderList * render_list =nullptr;
MaterialInstance * material_instance[6]{};
Renderable * render_obj[6] {};
Material * material =nullptr;
struct
{
MaterialInstance * mi;
Renderable * r;
}render_obj[DRAW_OBJECT_COUNT]{};
Pipeline * pipeline =nullptr;
@@ -50,49 +47,55 @@ private:
bool InitMaterial()
{
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureColor2D");
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureColor2D",Prim::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=true;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureColor2D(&cfg);
/* for(uint i=0;i<6;i++)
{
material_instance[i]=db->CreateMaterialInstance(mci);
material=db->CreateMaterial(mci);
if(!material_instance[i])
if(!material)
return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].mi=db->CreateMaterialInstance(material);
if(!render_obj[i].mi)
return(false);
material_instance[i]->SetFloat4(0,color_data[i]);
}*/
Color4f color=GetColor4f((COLOR)(i+int(COLOR::Blue)),1.0);
render_obj[i].mi->WriteMIData(color); //设置MaterialInstance的数据
}
}
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
// pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Triangles);
return pipeline;
}
bool InitVBO()
bool InitVBOAndRenderList()
{
//RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
//if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
//
//render_obj=rpc.Create(material_instance,pipeline);
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
//if(!render_obj)
// return(false);
//
//for(uint i=0;i<6;i++)
//{
// render_root.CreateSubNode(rotate(deg2rad(60*i),Vector3f(0,0,1)),render_obj);
//}
if(!render_obj[i].r)
return(false);
//render_root.RefreshMatrix();
render_root.CreateSubNode(rotate(deg2rad(360/DRAW_OBJECT_COUNT*i),Vector3f(0,0,1)),render_obj[i].r);
}
//render_list->Expend(&render_root);
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
@@ -114,7 +117,7 @@ public:
if(!InitMaterial())
return(false);
if(!InitVBO())
if(!InitVBOAndRenderList())
return(false);
BuildCommandBuffer(render_list);

View File

@@ -1,5 +1,4 @@
// first_triangle
// 该范例主要演示使用NDC坐标系直接绘制一个渐变色的三角形
// 该范例主要演示使用NDC坐标系直接绘制一个渐变色的三角形
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
@@ -87,7 +86,7 @@ private:
bool InitAutoMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2d");
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2d",Prim::Triangles);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;

View File

@@ -1,5 +1,4 @@
// second_triangle
// 该范例主要演示使用2D坐系统直接绘制一个渐变色的三角形,使用UBO传递Viewport信息
// 该范例主要演示使用2D坐系统直接绘制一个渐变色的三角形,使用UBO传递Viewport信息
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
@@ -45,7 +44,7 @@ private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D");
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"VertexColor2D",Prim::Triangles);
#ifdef USE_ZERO2ONE_COORD
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;

View File

@@ -2,6 +2,10 @@
SET(VULKAN_APP_FRAMEWORK ${CMAKE_CURRENT_SOURCE_DIR}/common/VulkanAppFramework.h)
add_subdirectory(Basic)
add_subdirectory(Texture)
add_subdirectory(Gizmo)
add_subdirectory(Vulkan)
add_subdirectory(2dVector)
add_subdirectory(GUI)

View File

@@ -0,0 +1,13 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Gizmo")
endmacro()
CreateProject(PlaneGrid3D PlaneGrid3D.cpp)

View File

@@ -0,0 +1,16 @@
macro(CreateProject name)
add_executable(${name} ${ARGN} ${VULKAN_APP_FRAMEWORK})
target_link_libraries(${name} ${ULRE})
IF(MSVC)
set_target_properties(${name} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${ULRE_RUNTIME_PATH})
set_property(TARGET ${name} PROPERTY VS_DPI_AWARE "PerMonitor")
ENDIF()
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Texture")
endmacro()
CreateProject(05_texture_format texture_format_list.cpp)
CreateProject(06_texture_quad texture_quad.cpp)
CreateProject(07_texture_rect texture_rect.cpp)
CreateProject(08_texture_rect_array texture_rect_array.cpp)

View File

@@ -1,10 +1,11 @@
// 2.texture_rect
// 该示例是1.indices_rect的进化演示在矩形上贴上贴图
// 画一个带纹理的四边形
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
using namespace hgl;
@@ -21,26 +22,18 @@ constexpr uint32_t VERTEX_COUNT=4;
constexpr float position_data[VERTEX_COUNT][2]=
{
{0, 0},
{SCREEN_WIDTH, 0},
{0, SCREEN_HEIGHT},
{SCREEN_WIDTH, SCREEN_HEIGHT}
{-1, -1},
{ 1, -1},
{ 1, 1},
{-1, 1},
};
constexpr float tex_coord_data[VERTEX_COUNT][2]=
{
{0,0},
{1,0},
{0,1},
{1,1}
};
constexpr uint32_t INDEX_COUNT=6;
constexpr uint16 index_data[INDEX_COUNT]=
{
0,1,3,
0,3,2
{1,1},
{0,1}
};
class TestApp:public VulkanApplicationFramework
@@ -49,22 +42,30 @@ private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Renderable * renderable =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/Texture2D"));
if(!material_instance)return(false);
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"PureTexture2D",Prim::Fan);
BindCameraUBO(material_instance);
cfg.coordinate_system=CoordinateSystem2D::NDC;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreatePureTexture2D(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::Fan); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
@@ -73,23 +74,26 @@ private:
sampler=db->CreateSampler();
if(!material_instance->BindImageSampler(DescriptorSetType::Value,"tex",texture,sampler))return(false);
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
material_instance=db->CreateMaterialInstance(material);
return(true);
}
bool InitVBO()
{
auto primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
RenderablePrimitiveCreater rpc(db,VERTEX_COUNT);
if(!primitive->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(VAN::TexCoord,db->CreateVBO(VF_V2F,VERTEX_COUNT,tex_coord_data)))return(false);
if(!primitive->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false);
if(!rpc.SetVBO(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
render_obj=rpc.Create(material_instance,pipeline);
return(render_obj);
}
public:
@@ -105,7 +109,7 @@ public:
if(!InitVBO())
return(false);
BuildCommandBuffer(renderable);
BuildCommandBuffer(render_obj);
return(true);
}
@@ -114,7 +118,7 @@ public:
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(renderable);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework

View File

@@ -0,0 +1,136 @@
// 画一个带纹理的矩形2D模式专用
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
constexpr float position_data[4]=
{
0, //left
0, //top
1, //right
1 //bottom
};
constexpr float tex_coord_data[4]=
{
0,0,
1,1
};
class TestApp:public VulkanApplicationFramework
{
private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"RectTexture2D",Prim::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=false;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateRectTexture2D(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"),true);
if(!texture)return(false);
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
material_instance=db->CreateMaterialInstance(material);
return(true);
}
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,1);
if(!rpc.SetVBO(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
render_obj=rpc.Create(material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_obj);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -0,0 +1,211 @@
// 画一个带纹理的矩形2D模式专用
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
#include<hgl/filesystem/Filename.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
//Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
float position_data[4]=
{
0, //left
0, //top
1, //right
1 //bottom
};
constexpr float tex_coord_data[4]=
{
0,0,
1,1
};
constexpr const os_char *tex_filename[]=
{
OS_TEXT("001-online resume.Tex2D"),
OS_TEXT("002-salary.Tex2D"),
OS_TEXT("003-application.Tex2D"),
OS_TEXT("004-job interview.Tex2D")
};
constexpr const size_t TexCount=sizeof(tex_filename)/sizeof(os_char *);
class TestApp:public VulkanApplicationFramework
{
private:
SceneNode render_root;
RenderList * render_list =nullptr;
Texture2DArray * texture =nullptr;
Sampler * sampler =nullptr;
Material * material =nullptr;
Pipeline * pipeline =nullptr;
DeviceBuffer * tex_id_ubo =nullptr;
struct
{
MaterialInstance * mi;
Renderable * r;
}render_obj[TexCount]{};
private:
bool InitTexture()
{
texture=db->CreateTexture2DArray( 512,512, ///<纹理尺寸
TexCount, ///<纹理层数
PF_BC1_RGBAUN, ///<纹理格式
false); ///<是否自动产生mipmaps
if(!texture)return(false);
OSString filename;
for(uint i=0;i<TexCount;i++)
{
filename=filesystem::MergeFilename(OS_TEXT("res/image/icon/freepik"),tex_filename[i]);
if(!db->LoadTexture2DToArray(texture,i,filename))
return(false);
}
return(true);
}
bool InitMaterial()
{
mtl::Material2DCreateConfig cfg(device->GetDeviceAttribute(),"RectTexture2DArray",Prim::SolidRectangles);
cfg.coordinate_system=CoordinateSystem2D::ZeroToOne;
cfg.local_to_world=true;
AutoDelete<mtl::MaterialCreateInfo> mci=mtl::CreateRectTexture2DArray(&cfg);
material=db->CreateMaterial(mci);
if(!material)
return(false);
pipeline=CreatePipeline(material,InlinePipeline::Solid2D,Prim::SolidRectangles); //等同上一行为Framework重载默认使用swapchain的render target
if(!pipeline)
return(false);
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
for(uint32_t i=0;i<TexCount;i++)
{
render_obj[i].mi=db->CreateMaterialInstance(material);
if(!render_obj[i].mi)
return(false);
render_obj[i].mi->WriteMIData(i); //设置MaterialInstance的数据
}
return(true);
}
bool InitVBOAndRenderList()
{
RenderablePrimitiveCreater rpc(db,1);
position_data[2]=1.0f/float(TexCount);
if(!rpc.SetVBO(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVBO(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
Vector3f offset(1.0f/float(TexCount),0,0);
for(uint32_t i=0;i<TexCount;i++)
{
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
if(!render_obj[i].r)
return(false);
offset.x=position_data[2]*float(i);
render_root.CreateSubNode(translate(offset),render_obj[i].r);
}
render_root.RefreshMatrix();
render_list->Expend(&render_root);
return(true);
}
public:
~TestApp()
{
SAFE_CLEAR(render_list);
}
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH*TexCount,SCREEN_HEIGHT))
return(false);
render_list=new RenderList(device);
if(!InitTexture())
return(false);
if(!InitMaterial())
return(false);
if(!InitVBOAndRenderList())
return(false);
BuildCommandBuffer(render_list);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_list);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -10,22 +10,11 @@
set_property(TARGET ${name} PROPERTY FOLDER "ULRE/Example/Vulkan/${group}")
endmacro()
CreateProject("Basic" 1st_draw_triangle_in_NDC first_triangle.cpp)
CreateProject("Basic" 2nd_draw_triangle_use_UBO second_triangle.cpp)
CreateProject("Basic" 3rd_draw_triangle_use_RenderList third_triangle.cpp)
CreateProject("Basic" 4th_draw_triangle_use_MaterialInstance fourth_triangle.cpp)
#CreateProject("Basic" FragCoord FragCoordTest.cpp)
#CreateProject("Basic" indices_rect indices_rect.cpp)
#CreateProject("Basic" FullScreenTriangle FullScreenTriangle.cpp)
#CreateProject("Basic" InstanceTriangle InstanceTriangle.cpp)
CreateProject("Texture" TextureFormat TextureFormat.cpp)
#CreateProject("Texture" texture_rect texture_rect.cpp)
#CreateProject("Texture" HQFilterTexture HQFilterTexture.cpp)
#CreateProject(06.Geometry2D Geometry2D.cpp)
#CreateProject("Geometry2D" RectanglePrimitive RectanglePrimitive.cpp)
#CreateProject("Tile" DrawTile DrawTile.cpp)
#CreateProject("Tile" DrawText DrawText.cpp)

View File

@@ -1,87 +0,0 @@
// 全屏三角形
// 该范例用于演示使用索引画一个覆盖全屏的三角形但是不传递任何顶点信息顶点坐标在vertex shader中通过gl_VertexIndex计算出来。
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable *renderable =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/fullscreen"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles);
return pipeline;
}
bool InitVBO()
{
auto primitive=db->CreatePrimitive(3);
if(!primitive)return(false);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(renderable);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(renderable);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -1,103 +0,0 @@
// Instance Triangle
// 基本的Instance绘制测试用例,不使用场景树
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_SIZE=512;
constexpr uint32_t VERTEX_COUNT=3;
constexpr float position_data[VERTEX_COUNT][2]=
{
{0,0},
{0.25,-0.75},
{0,-1}
};
constexpr float color_data[VERTEX_COUNT][4]=
{ {1,0,0,1},
{0,1,0,1},
{0,0,1,1}
};
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/VertexColor2DNDC"));
if(!material_instance)
return(false);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
Primitive *primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position, db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data )))return(false);
if(!primitive->Set(VAN::Color, db->CreateVBO(VF_V4F,VERTEX_COUNT,color_data )))return(false);
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
if(!BuildCommandBuffer(render_obj))
return(false);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -1,117 +0,0 @@
// 2.RectanglePrimivate
// 该示例是texture_rect的进化演示使用GeometryShader画矩形
#include"VulkanAppFramework.h"
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
VK_NAMESPACE_BEGIN
Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename);
VK_NAMESPACE_END
constexpr uint32_t SCREEN_SIZE=512;
constexpr uint32_t VERTEX_COUNT=1;
constexpr float BORDER=0.1f;
constexpr float position_data[4]=
{
SCREEN_SIZE*BORDER, SCREEN_SIZE*BORDER,
SCREEN_SIZE*(1.0-BORDER), SCREEN_SIZE*(1.0-BORDER)
};
constexpr float tex_coord_data[4]=
{
0,0,1,1
};
class TestApp:public VulkanApplicationFramework
{
private:
Texture2D * texture =nullptr;
Sampler * sampler =nullptr;
MaterialInstance * material_instance =nullptr;
Primitive * primitive =nullptr;
Renderable * render_obj =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/TextureRect2D"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles);
if(!pipeline)return(false);
texture=db->LoadTexture2D(OS_TEXT("res/image/lena.Tex2D"));
if(!texture)return(false);
sampler=db->CreateSampler();
if(!material_instance->BindImageSampler(DescriptorSetType::Value,"tex",texture,sampler))return(false);
return(true);
}
bool InitVBO()
{
primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
primitive->Set(VAN::Position,db->CreateVBO(VF_V4F,VERTEX_COUNT,position_data));
primitive->Set(VAN::TexCoord,db->CreateVBO(VF_V4F,VERTEX_COUNT,tex_coord_data));
render_obj=db->CreateRenderable(primitive,material_instance,pipeline);
return(render_obj);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(render_obj);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(render_obj);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -1,111 +0,0 @@
// indices_rect
// 该示例演示使用索引数据画一个矩形,并使用了颜色材质
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
using namespace hgl;
using namespace hgl::graph;
constexpr uint32_t SCREEN_WIDTH=256;
constexpr uint32_t SCREEN_HEIGHT=256;
constexpr uint32_t VERTEX_COUNT=4;
static Vector4f color(1,1,1,1);
constexpr float position_data[VERTEX_COUNT][2]=
{
{0,0},
{SCREEN_WIDTH,0},
{0,SCREEN_HEIGHT},
{SCREEN_WIDTH,SCREEN_HEIGHT}
};
constexpr uint32_t INDEX_COUNT=6;
constexpr uint16 index_data[INDEX_COUNT]=
{
0,1,3,
0,3,2
};
class TestApp:public VulkanApplicationFramework
{
private:
MaterialInstance * material_instance =nullptr;
Renderable *renderable =nullptr;
Pipeline * pipeline =nullptr;
private:
bool InitMaterial()
{
material_instance=db->CreateMaterialInstance(OS_TEXT("res/material/FragColor"));
if(!material_instance)return(false);
BindCameraUBO(material_instance);
// pipeline=db->CreatePipeline(material_instance,sc_render_target,OS_TEXT("res/pipeline/solid2d"));
pipeline=CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::Triangles); //等同上一行为Framework重载默认使用swapchain的render target
return pipeline;
}
bool InitVBO()
{
auto primitive=db->CreatePrimitive(VERTEX_COUNT);
if(!primitive)return(false);
if(!primitive->Set(VAN::Position,db->CreateVBO(VF_V2F,VERTEX_COUNT,position_data)))return(false);
if(!primitive->Set(db->CreateIBO16(INDEX_COUNT,index_data)))return(false);
renderable=db->CreateRenderable(primitive,material_instance,pipeline);
return(true);
}
public:
bool Init()
{
if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT))
return(false);
if(!InitMaterial())
return(false);
if(!InitVBO())
return(false);
BuildCommandBuffer(renderable);
return(true);
}
void Resize(int w,int h)override
{
VulkanApplicationFramework::Resize(w,h);
BuildCommandBuffer(renderable);
}
};//class TestApp:public VulkanApplicationFramework
int main(int,char **)
{
#ifdef _DEBUG
if(!CheckStrideBytesByFormat())
return 0xff;
#endif//
TestApp app;
if(!app.Init())
return(-1);
while(app.Run());
return 0;
}

View File

@@ -510,9 +510,9 @@ public:
return ubo_camera_info;
}
bool BindCameraUBO(MaterialInstance *mi)
bool BindCameraUBO(Material *mtl)
{
return mi->BindUBO(DescriptorSetType::Global,"g_camera",ubo_camera_info);
return mtl->BindUBO(DescriptorSetType::Global,"g_camera",ubo_camera_info);
}
virtual void BuildCommandBuffer(uint32_t index)=0;

View File

@@ -21,7 +21,7 @@ namespace hgl
~Bitmap2DLoader();
void *OnBegin(uint32 total_bytes) override;
void OnEnd() override {}
bool OnEnd() override {return(false);}
BitmapData *GetBitmap();
};//class Bitmap2DLoader

View File

@@ -1,12 +1,12 @@
#pragma once
#pragma once
#include<hgl/graph/RenderNode.h>
#include<hgl/graph/VKVBOList.h>
VK_NAMESPACE_BEGIN
struct RenderExtraBuffer;
class RenderAssignBuffer;
/**
* ͬһ<EFBFBD><EFBFBD><EFBFBD>ʵĶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD>б<EFBFBD>
* 同一材质的对象渲染列表
*/
class MaterialRenderList
{
@@ -19,7 +19,7 @@ class MaterialRenderList
private:
RenderExtraBuffer *extra_buffer;
RenderAssignBuffer *assign_buffer;
struct RenderItem
{
@@ -39,13 +39,14 @@ private:
DataArray<RenderItem> ri_array;
uint ri_count;
void StatMI();
void Stat();
protected:
VBOList * vbo_list;
MaterialInstance * last_mi;
const VIL * last_vil;
Pipeline * last_pipeline;
const VertexInputData * last_vid;
uint last_index;

View File

@@ -23,7 +23,7 @@ namespace hgl
using RenderNodeList=List<RenderNode>;
using MaterialInstanceSets=SortedSets<MaterialInstance *>;
using MaterialInstanceSets=SortedSets<MaterialInstance *>; ///<材质实例集合
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_RENDER_NODE_INCLUDE

View File

@@ -0,0 +1,84 @@
#pragma once
#include<hgl/graph/VK.h>
VK_NAMESPACE_BEGIN
enum class ResourceType
{
Unknown=0,
VkInstance,
VkPhysicalDevice,
VkDevice,
VertexInputLayout,
Material,
MaterialInstance,
FrameBuffer,
Texture,
Sampler,
VertexBuffer,
IndexBuffer,
IndirectBuffer,
UniformBuffer,
StorageBuffer,
Skeleton, ///<骨骼信息
SkeletonAnime, ///<骨骼动画信息
Primitive, ///<原始的单个模型数据由多个VBO+Index组成
RawMesh, ///<原始的静态模型数据由一个Primitive和一个MaterialInstance组成
StaticMesh, ///<静态模型数据由一个或多个RawMesh组成
SkeletonMesh, ///<骨骼模型数据由一个或多个StaticMesh组成
Font,
Scene,
Animation,
Audio,
Other,
ENUM_CLASS_RANGE(Unknown,Other)
};
enum class ResourcePlace
{
Unknown=0,
Memory, ///<内存
Device, ///<设备(如显存)
Disk, ///<硬盘
LAN, ///<局域网
WAN, ///<广域网
Other,
ENUM_CLASS_RANGE(Device,Other)
};
struct RenderResourceID
{
union
{
struct
{
uint device:1; ///<在设备
uint memory:1; ///<在内存
uint disk:1; ///<在硬盘
uint network:1; ///<在网络
};
uint8 place; ///<数据所在位置
};
uint16 resource_type; ///<资源类型对应ResourceType枚举
uint16 thread_id; ///<线程ID
uint32 id; ///<资源ID
};
VK_NAMESPACE_END

View File

@@ -86,7 +86,7 @@ namespace hgl
protected:
virtual void *OnBegin(uint32)=0;
virtual void OnEnd()=0;
virtual bool OnEnd()=0;
virtual void OnError(){}
public:
@@ -207,7 +207,7 @@ namespace hgl
{
protected: // override functions
uint32 GetPixelsCount()const override{return file_header.length;}
uint32 GetPixelsCount()const override{return file_header.length*file_header.layers;}
uint32 GetTotalBytes()const override
{
if(file_header.mipmaps<=1)
@@ -230,7 +230,7 @@ namespace hgl
{
protected: // override functions
uint32 GetPixelsCount()const override{return file_header.width*file_header.height;}
uint32 GetPixelsCount()const override{return file_header.width*file_header.height*file_header.layers;}
uint32 GetTotalBytes()const override
{
if(file_header.mipmaps<=1)

View File

@@ -24,6 +24,8 @@ class TileFont;
class FontSource;
class GPUArrayBuffer;
struct CopyBufferToImageInfo;
class GPUDevice
{
GPUDeviceAttribute *attr;
@@ -151,7 +153,15 @@ public: //Image
private: //texture
bool CommitTexture (Texture *,DeviceBuffer *buf,const VkBufferImageCopy *,const int count,const uint32_t layer_count,VkPipelineStageFlags);//=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
bool CopyBufferToImage (const CopyBufferToImageInfo *info,VkPipelineStageFlags destinationStage);
bool CopyBufferToImage (Texture *,DeviceBuffer *buf,const VkBufferImageCopy *,const int count,const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags);//=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
bool CopyBufferToImage2D (Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *bic_list,const int bic_count, VkPipelineStageFlags dstStage){return CopyBufferToImage(tex,buf,bic_list, bic_count, 0,1,dstStage);}
bool CopyBufferToImage2D (Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *bic, VkPipelineStageFlags dstStage){return CopyBufferToImage(tex,buf,bic, 1, 0,1,dstStage);}
bool CopyBufferToImageCube (Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *bic_list,const int bic_count, VkPipelineStageFlags dstStage){return CopyBufferToImage(tex,buf,bic_list, bic_count, 0,6,dstStage);}
bool CopyBufferToImageCube (Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *bic, VkPipelineStageFlags dstStage){return CopyBufferToImage(tex,buf,bic, 1, 0,6,dstStage);}
bool CommitTexture2D (Texture2D *,DeviceBuffer *buf,VkPipelineStageFlags stage);
bool CommitTexture2DMipmaps (Texture2D *,DeviceBuffer *buf,const VkExtent3D &,uint32_t);
@@ -170,6 +180,10 @@ public: //Texture
Texture2D *CreateTexture2D(TextureData *);
Texture2D *CreateTexture2D(TextureCreateInfo *ci);
Texture2DArray *CreateTexture2DArray(TextureData *);
Texture2DArray *CreateTexture2DArray(TextureCreateInfo *ci);
Texture2DArray *CreateTexture2DArray(const uint32_t w,const uint32_t h,const uint32 l,const VkFormat fmt,const bool mipmaps);
TextureCube *CreateTextureCube(TextureData *);
TextureCube *CreateTextureCube(TextureCreateInfo *ci);
@@ -179,6 +193,10 @@ public: //Texture
bool ChangeTexture2D(Texture2D *,DeviceBuffer *buf, const RectScope2ui &, VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
bool ChangeTexture2D(Texture2D *,void *data,const uint32_t size,const RectScope2ui &, VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
// bool ChangeTexture2DArray(Texture2DArray *,DeviceBuffer *buf, const List<Image2DRegion> &, const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
bool ChangeTexture2DArray(Texture2DArray *,DeviceBuffer *buf, const RectScope2ui &, const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
bool ChangeTexture2DArray(Texture2DArray *,void *data,const uint32_t size,const RectScope2ui &, const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags=VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
public: //
Sampler *CreateSampler(VkSamplerCreateInfo *sci=nullptr);

View File

@@ -92,6 +92,8 @@ public:
hgl_zero(*this);
descriptor_pool=1024;
geometry_shader=true;
}
};

View File

@@ -6,6 +6,11 @@
#include<hgl/type/String.h>
#include<hgl/graph/VKShaderModuleMap.h>
#include<hgl/graph/VKDescriptorSetType.h>
namespace hgl
{
class ActiveMemoryBlockManager;
}
VK_NAMESPACE_BEGIN
using ShaderStageCreateInfoList=List<VkPipelineShaderStageCreateInfo>;
@@ -30,15 +35,18 @@ class Material
MaterialParameters *mp_array[DESCRIPTOR_SET_TYPE_COUNT];
uint32_t mi_data_bytes; ///<实例数据大小
uint32_t mi_max_count; ///<最大实例数量(注代表一次drawcall大小而不是整个的大小)
uint32_t mi_max_count; ///<实例一次渲染最大数量限制
ActiveMemoryBlockManager *mi_data_manager;
private:
friend class RenderResource;
Material(const AnsiString &);
public:
Material(const AnsiString &);
virtual ~Material();
const UTF8String & GetName ()const{return name;}
@@ -62,12 +70,26 @@ public:
const bool hasSet (const DescriptorSetType &type)const;
const VIL * GetDefaultVIL()const;
VIL * CreateVIL(const VILConfig *format_map=nullptr);
bool Release(VIL *);
const uint GetVILCount();
public:
bool BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
bool BindSSBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
bool BindImageSampler(const DescriptorSetType &type,const AnsiString &name,Texture *tex,Sampler *sampler);
public:
const bool HasMI ()const{return mi_data_bytes>0;}
const uint32_t GetMIDataBytes ()const{return mi_data_bytes;}
const uint32_t GetMIMaxCount ()const{return mi_max_count;}
void ReleaseMI(int); ///<释放材质实例
void *GetMIData(int); ///<取得指定ID号的材质实例数据访问指针
MaterialInstance *CreateMI(const VILConfig *vil_cfg=nullptr);
};//class Material

View File

@@ -50,6 +50,8 @@ protected:
VIL *vil;
int mi_id;
public:
Material * GetMaterial () {return material;}
@@ -60,15 +62,21 @@ private:
friend class Material;
MaterialInstance(Material *,VIL *);
MaterialInstance(Material *,VIL *,const int);
public:
virtual ~MaterialInstance()=default;
bool BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
bool BindSSBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic=false);
bool BindImageSampler(const DescriptorSetType &type,const AnsiString &name,Texture *tex,Sampler *sampler);
virtual ~MaterialInstance()
{
material->ReleaseMI(mi_id);
}
const int GetMIID ()const{return mi_id;} ///<取得材质实例ID
void * GetMIData (){return material->GetMIData(mi_id);} ///<取得材质实例数据
void WriteMIData (const void *data,const int size); ///<写入材质实例数据
template<typename T>
void WriteMIData (const T &data){WriteMIData(&data,sizeof(T));} ///<写入材质实例数据
};//class MaterialInstance
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_MATERIAL_INSTANCE_INCLUDE

View File

@@ -54,9 +54,15 @@ public:
public:
Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &, const Prim &prim,const bool prim_restart=false);
Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *, const Prim &prim,const bool prim_restart=false);
Pipeline *CreatePipeline(MaterialInstance *, const OSString &, const Prim &prim,const bool prim_restart=false);
Pipeline *CreatePipeline(Material *,const VIL *,const PipelineData *, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(Material *,const VIL *,const InlinePipeline &, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(Material *mtl, const PipelineData *, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(Material *mtl, const InlinePipeline &, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(MaterialInstance *, const InlinePipeline &, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(MaterialInstance *, const PipelineData *, const Prim &,const bool prim_restart=false);
Pipeline *CreatePipeline(MaterialInstance *, const OSString &, const Prim &,const bool prim_restart=false);
};//class RenderPass
VK_NAMESPACE_END
#endif//HGL_GRAPH_VULKAN_RENDER_PASS_INCLUDE

View File

@@ -117,6 +117,9 @@ public: //texture
Texture2D * LoadTexture2D(const OSString &,bool auto_mipmaps=false);
TextureCube * LoadTextureCube(const OSString &,bool auto_mipmaps=false);
Texture2DArray * CreateTexture2DArray(const uint32_t width,const uint32_t height,const uint32_t layer,const VkFormat &fmt,bool auto_mipmaps=false);
bool LoadTexture2DToArray(Texture2DArray *,const uint32_t layer,const OSString &);
public: //Get
Material * GetMaterial (const MaterialID &id){return rm_material.Get(id);}

View File

@@ -33,9 +33,9 @@ public:
return(true);
}
bool SetIBO(const IndexType &it,const void *buf)
bool SetIBO(const IndexType &it,const void *buf,const uint32_t index_count)
{
IndexBuffer *ibo=rr->CreateIBO(it,vertex_count,buf);
IndexBuffer *ibo=rr->CreateIBO(it,index_count,buf);
if(!ibo)
return(false);

View File

@@ -63,8 +63,8 @@ class Texture2D:public Texture
{
public:
Texture2D(VkDevice dev,TextureData *td):Texture(dev,td){}
~Texture2D()=default;
using Texture::Texture;
virtual ~Texture2D()=default;
static VkImageViewType GetImageViewType(){return VK_IMAGE_VIEW_TYPE_2D;}
@@ -72,10 +72,19 @@ public:
const uint32_t GetHeight()const{return data?data->image_view->GetExtent().height:0;}
};//class Texture2D:public Texture
//class Texture2DArray:public Texture
//{
// uint32_t width,height,count;
//};//class Texture2DArray:public Texture
class Texture2DArray:public Texture
{
public:
using Texture::Texture;
virtual ~Texture2DArray()=default;
static VkImageViewType GetImageViewType(){return VK_IMAGE_VIEW_TYPE_2D_ARRAY;}
const uint32_t GetWidth ()const{return data?data->image_view->GetExtent().width:0;}
const uint32_t GetHeight()const{return data?data->image_view->GetExtent().height:0;}
const uint32_t GetLayer ()const{return data?data->image_view->GetExtent().depth:0;}
};//class Texture2DArray:public Texture
//class Texture3D:public Texture
//{

View File

@@ -20,13 +20,13 @@ struct TextureCreateInfo
VkImageLayout image_layout;
VkImage image; //如果没有IMAGE则创建。交换链等会直接提供image所以存在外部传入现像)
DeviceMemory * memory; //同时需分配内存并绑定
DeviceMemory * memory; //同时需分配内存并绑定
ImageView * image_view; //如果没有imageview则创建
void * pixels; //如果没有buffer但有pixels则根据pixels和以上条件创建buffer
VkDeviceSize total_bytes;
DeviceBuffer * buffer; //如果pixels也没有则代表不会立即写入图像数据
DeviceBuffer * buffer; //如果pixels也没有则代表不会立即写入图像数据
public:

View File

@@ -3,6 +3,7 @@
#include<hgl/graph/mtl/MaterialConfig.h>
#include<hgl/graph/CoordinateSystem.h>
#include<hgl/graph/VertexAttrib.h>
STD_MTL_NAMESPACE_BEGIN
struct Material2DCreateConfig:public MaterialCreateConfig
@@ -11,9 +12,11 @@ struct Material2DCreateConfig:public MaterialCreateConfig
bool local_to_world; ///<包含LocalToWorld矩阵
VAT position_format; ///<position格式
public:
Material2DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name):MaterialCreateConfig(da,name)
Material2DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p):MaterialCreateConfig(da,name,p)
{
rt_output.color=1; //输出一个颜色
rt_output.depth=false; //不输出深度
@@ -21,10 +24,19 @@ public:
coordinate_system=CoordinateSystem2D::NDC;
local_to_world=false;
if(prim==Prim::SolidRectangles
||prim==Prim::WireRectangles)
position_format=VAT_VEC4;
else
position_format=VAT_VEC2;
}
};//struct Material2DCreateConfig:public MaterialCreateConfig
MaterialCreateInfo *CreateVertexColor2D(const Material2DCreateConfig *);
MaterialCreateInfo *CreatePureColor2D(const Material2DCreateConfig *);
MaterialCreateInfo *CreatePureTexture2D(const Material2DCreateConfig *);
MaterialCreateInfo *CreateRectTexture2D(Material2DCreateConfig *);
MaterialCreateInfo *CreateRectTexture2DArray(Material2DCreateConfig *);
STD_MTL_NAMESPACE_END
#endif//HGL_GRAPH_MTL_2D_CREATE_CONFIG_INCLUDE

View File

@@ -0,0 +1,33 @@
#pragma once
#include<hgl/graph/mtl/MaterialConfig.h>
#include<hgl/graph/CoordinateSystem.h>
#include<hgl/graph/VertexAttrib.h>
STD_MTL_NAMESPACE_BEGIN
struct Material3DCreateConfig:public MaterialCreateConfig
{
bool local_to_world; ///<包含LocalToWorld矩阵
VAT position_format; ///<position格式
public:
Material3DCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p):MaterialCreateConfig(da,name,p)
{
rt_output.color=1; //输出一个颜色
rt_output.depth=true; //不输出深度
rt_output.stencil=false; //不输出stencil
local_to_world=false;
position_format=VAT_VEC3;
}
};//struct Material3DCreateConfig:public MaterialCreateConfig
//MaterialCreateInfo *CreateVertexColor2D(const Material2DCreateConfig *);
//MaterialCreateInfo *CreatePureColor2D(const Material2DCreateConfig *);
//MaterialCreateInfo *CreatePureTexture2D(const Material2DCreateConfig *);
//MaterialCreateInfo *CreateRectTexture2D(Material2DCreateConfig *);
//MaterialCreateInfo *CreateRectTexture2DArray(Material2DCreateConfig *);
STD_MTL_NAMESPACE_END

View File

@@ -22,15 +22,19 @@ struct MaterialCreateConfig
uint32 shader_stage_flag_bit; ///<需要的shader
Prim prim; ///<图元类型
public:
MaterialCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name)
MaterialCreateConfig(const GPUDeviceAttribute *da,const AnsiString &name,const Prim &p)
{
dev_attr=da;
mtl_name=name;
shader_stage_flag_bit=VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT;
prim=p;
}
};//struct MaterialCreateConfig
STD_MTL_NAMESPACE_END

View File

@@ -0,0 +1,15 @@
#pragma once
namespace hgl
{
namespace graph
{
namespace mtl
{
namespace SamplerName
{
constexpr const char Color[] = "TextureColor";
}//namespace SamplerName
}//namespace mtl
}//namespace graph
}//namespace hgl

View File

@@ -56,7 +56,7 @@ constexpr const ShaderBufferSource SBS_LocalToWorld=
constexpr const char MaterialInstanceStruct[]="MaterialInstance";
constexpr const ShaderBufferSource SBS_MaterialInstanceData=
constexpr const ShaderBufferSource SBS_MaterialInstance=
{
"MaterialInstanceData",
"mtl",

View File

@@ -46,6 +46,7 @@ protected:
virtual bool ProcHeader(){return(true);}
virtual bool ProcDefine();
virtual bool ProcLayout(){return(true);}
virtual bool ProcSubpassInput();
virtual bool ProcInput(ShaderCreateInfo *);
@@ -57,7 +58,7 @@ protected:
virtual bool ProcUBO();
virtual bool ProcSSBO();
virtual bool ProcConst();
virtual bool ProcConstantID();
virtual bool ProcSampler();
bool CompileToSPV();

View File

@@ -5,9 +5,17 @@
namespace hgl{namespace graph{
class ShaderCreateInfoGeometry:public ShaderCreateInfo
{
AnsiString input_prim;
AnsiString output_prim;
uint32_t max_vertices;
public:
ShaderCreateInfoGeometry(MaterialDescriptorInfo *m):ShaderCreateInfo(VK_SHADER_STAGE_GEOMETRY_BIT,m){}
~ShaderCreateInfoGeometry()=default;
bool SetGeom(const Prim &ip,const Prim &op,const uint32_t mv);
bool ProcLayout() override;
};
}}//namespace hgl::graph

View File

@@ -44,7 +44,8 @@ SET(SCENE_GRAPH_HEADER ${SG_INCLUDE_PATH}/SceneInfo.h
SET(SCENE_GRAPH_SOURCE RenderList.cpp
MaterialRenderList.cpp
RenderExtraBuffer.h
RenderAssignBuffer.h
RenderAssignBuffer.cpp
SceneNode.cpp
SceneOrient.cpp)
@@ -126,11 +127,13 @@ SET(VK_DEVICE_TEXTURE_SOURCE Vulkan/Texture/BufferImageCopy2D.h
Vulkan/Texture/GenMipmaps.cpp
Vulkan/Texture/VKDeviceTexture.cpp
Vulkan/Texture/VKDeviceTexture2D.cpp
Vulkan/Texture/VKDeviceTexture2DArray.cpp
Vulkan/Texture/VKDeviceTextureCube.cpp)
SET(VK_TEXTURE_LOADER_SOURCE ${SG_INCLUDE_PATH}/VKTextureCreateInfo.h
Vulkan/Texture/VKTextureLoader.h
Vulkan/Texture/VKTexture2DLoader.cpp
Vulkan/Texture/VKTexture2DArrayLoader.cpp
Vulkan/Texture/VKTextureCubeLoader.cpp)
SET(VK_DEVICE_CREATER_SOURCE ${SG_INCLUDE_PATH}/VKDevice.h

View File

@@ -3,8 +3,9 @@
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKVertexInput.h>
#include<hgl/graph/VKRenderAssign.h>
#include<hgl/util/sort/Sort.h>
#include"RenderExtraBuffer.h"
#include"RenderAssignBuffer.h"
/**
*
@@ -33,10 +34,10 @@ int Comparator<hgl::graph::RenderNode>::compare(const hgl::graph::RenderNode &ob
return off;
}
//比较材质实例
//比较顶点输入格式
{
off=ri_one->GetMaterialInstance()
-ri_two->GetMaterialInstance();
off=ri_one->GetMaterialInstance()->GetVIL()
-ri_two->GetMaterialInstance()->GetVIL();
if(off)
return off;
@@ -60,7 +61,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m)
device=d;
cmd_buf=nullptr;
mtl=m;
extra_buffer=nullptr;
assign_buffer=new RenderAssignBuffer(d,mtl->GetMIDataBytes());
vbo_list=new VBOList(mtl->GetVertexInput()->GetCount());
}
@@ -68,7 +69,7 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,Material *m)
MaterialRenderList::~MaterialRenderList()
{
SAFE_CLEAR(vbo_list);
SAFE_CLEAR(extra_buffer)
SAFE_CLEAR(assign_buffer)
}
void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat)
@@ -90,24 +91,13 @@ void MaterialRenderList::End()
if(node_count<=0)return;
if(!extra_buffer)
extra_buffer=new RenderExtraBuffer;
if(extra_buffer->node_count<node_count)
extra_buffer->NodeAlloc(device,node_count);
if(mtl->HasMI())
StatMI();
Stat();
//写入LocalToWorld数据
extra_buffer->WriteLocalToWorld(rn_list.GetData(),node_count);
const uint mi_count=mi_set.GetCount();
if(mi_count<=0)return;
//if(extra_buffer->mi_count<mi_count)
// extra_buffer->MIAlloc(device,mi_count,);
//extra_buffer->WriteMaterialInstance(rn_list.GetData(),node_count,mi_set);
assign_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
}
void MaterialRenderList::RenderItem::Set(Renderable *ri)
@@ -117,6 +107,19 @@ void MaterialRenderList::RenderItem::Set(Renderable *ri)
vid =ri->GetVertexInputData();
}
void MaterialRenderList::StatMI()
{
mi_set.Clear();
for(RenderNode &rn:rn_list)
mi_set.Add(rn.ri->GetMaterialInstance());
if(mi_set.GetCount()>mtl->GetMIMaxCount())
{
//超出最大数量了怎么办???
}
}
void MaterialRenderList::Stat()
{
const uint count=rn_list.GetCount();
@@ -125,10 +128,8 @@ void MaterialRenderList::Stat()
ri_array.Clear();
ri_array.Alloc(count);
mi_set.Clear();
RenderItem *ri=ri_array.GetData();
ri_count=1;
ri->first=0;
@@ -136,18 +137,16 @@ void MaterialRenderList::Stat()
ri->Set(rn->ri);
last_pipeline =ri->pipeline;
last_mi =ri->mi;
last_vil =ri->mi->GetVIL();
last_vid =ri->vid;
mi_set.Add(last_mi);
++rn;
for(uint i=1;i<count;i++)
{
{
if(last_pipeline==rn->ri->GetPipeline())
if(last_mi==rn->ri->GetMaterialInstance())
if(last_vid==rn->ri->GetVertexInputData())
if(last_vil==rn->ri->GetMaterialInstance()->GetVIL())
if(last_vid->Comp(rn->ri->GetVertexInputData()))
{
++ri->count;
++rn;
@@ -161,11 +160,8 @@ void MaterialRenderList::Stat()
ri->count=1;
ri->Set(rn->ri);
if(last_mi!=ri->mi)
mi_set.Add(ri->mi);
last_pipeline =ri->pipeline;
last_mi =ri->mi;
last_vil =ri->mi->GetVIL();
last_vid =ri->vid;
++rn;
@@ -176,15 +172,7 @@ void MaterialRenderList::Bind(MaterialInstance *mi)
{
if(!mi)return;
const VIL *vil=mi->GetVIL();
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
if(assign_binding_count>0)
{
mi->BindUBO(DescriptorSetType::PerFrame,"l2w",extra_buffer->assigns_l2w);
// mi->BindUBO(DescriptorSetType::PerFrame,"Assign",extra_buffer->assigns_mi);
}
assign_buffer->Bind(mi);
cmd_buf->BindDescriptorSets(mi->GetMaterial());
}
@@ -193,7 +181,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
{
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。
const VIL *vil=last_mi->GetVIL();
const VIL *vil=last_vil;
if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count)
return(false); //这里基本不太可能因为CreateRenderable时就会检查值是否一样
@@ -233,25 +221,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
// }
//}
//if(count<binding_count)//LocalToWorld组由RenderList合成
//{
// const uint l2w_binding_count=vil->GetCount(VertexInputGroup::LocalToWorld);
// if(l2w_binding_count>0) //有变换矩阵信息
// {
// if(l2w_binding_count!=4)
// return(false);
// hgl_cpy(buffer_list+count,extra_buffer->l2w_buffer,4);
// for(uint i=0;i<4;i++)
// buffer_offset[count+i]=ri_index*16; //mat4每列都是rgba32f自然是16字节
// count+=l2w_binding_count;
// }
//}
if(!vbo_list->IsFull())
if(!vbo_list->IsFull()) //Assign组
{
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
@@ -260,11 +230,10 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
if(assign_binding_count!=1)
return(false);
vbo_list->Add(extra_buffer->assigns_vbo->GetBuffer(),extra_buffer->assigns_vbo_strip*ri_index);
vbo_list->Add(assign_buffer->GetAssignVBO(),ASSIGN_VBO_STRIDE_BYTES*ri_index);
}
}
//if(count!=binding_count)
//{
// //还有没支持的绑定组????
@@ -272,7 +241,6 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
// return(false);
//}
//cmd_buf->BindVBO(0,count,buffer_list,buffer_offset);
cmd_buf->BindVBO(vbo_list);
return(true);
@@ -285,16 +253,15 @@ void MaterialRenderList::Render(RenderItem *ri)
cmd_buf->BindPipeline(ri->pipeline);
last_pipeline=ri->pipeline;
last_mi=nullptr;
last_vid=nullptr;
//这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive
}
if(last_mi!=ri->mi)
if(last_vil!=ri->mi->GetVIL())
{
Bind(ri->mi);
last_mi=ri->mi;
last_vil=ri->mi->GetVIL();
last_vid=nullptr;
}
@@ -333,7 +300,7 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
RenderItem *ri=ri_array.GetData();
last_pipeline =nullptr;
last_mi =nullptr;
last_vil =nullptr;
last_vid =nullptr;
for(uint i=0;i<ri_count;i++)

View File

@@ -0,0 +1,118 @@
#include"RenderAssignBuffer.h"
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/RenderNode.h>
#include<hgl/graph/VKRenderable.h>
#include<hgl/graph/VKRenderAssign.h>
#include<hgl/graph/mtl/UBOCommon.h>
VK_NAMESPACE_BEGIN
RenderAssignBuffer::RenderAssignBuffer(GPUDevice *dev,const uint mi_bytes)
{
hgl_zero(*this);
device=dev;
mi_data_bytes=mi_bytes;
ubo_mi=nullptr;
mi_count=0;
}
VkBuffer RenderAssignBuffer::GetAssignVBO()const
{
return vbo_assigns->GetBuffer();
}
void RenderAssignBuffer::Bind(MaterialInstance *mi)const
{
const VIL *vil=mi->GetVIL();
const uint assign_binding_count=vil->GetCount(VertexInputGroup::Assign);
if(assign_binding_count<=0)return;
Material *mtl=mi->GetMaterial();
mtl->BindUBO(DescriptorSetType::PerFrame,mtl::SBS_LocalToWorld.name,ubo_l2w);
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,ubo_mi);
}
void RenderAssignBuffer::Clear()
{
SAFE_CLEAR(ubo_l2w);
SAFE_CLEAR(ubo_mi);
SAFE_CLEAR(vbo_assigns);
node_count=0;
mi_count=0;
}
void RenderAssignBuffer::Alloc(const uint nc,const uint mc)
{
Clear();
{
node_count=nc;
ubo_l2w=device->CreateUBO(node_count*sizeof(Matrix4f));
}
if(mi_data_bytes>0&&mc>0)
{
mi_count=mc;
ubo_mi=device->CreateUBO(mi_data_bytes*mi_count);
}
vbo_assigns=device->CreateVBO(ASSIGN_VBO_FMT,node_count);
}
void RenderAssignBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
{
RenderNode *rn;
Alloc(count,mi_set.GetCount());
if(ubo_mi)
{
uint8 *mip=(uint8 *)(ubo_mi->Map());
for(MaterialInstance *mi:mi_set)
{
memcpy(mip,mi->GetMIData(),mi_data_bytes);
mip+=mi_data_bytes;
}
ubo_mi->Unmap();
}
uint16 *idp=(uint16 *)(vbo_assigns->Map());
{
Matrix4f *tp=(hgl::Matrix4f *)(ubo_l2w->Map());
Matrix4f *l2w=tp;
rn=render_node;
for(uint i=0;i<count;i++)
{
*l2w=rn->local_to_world;
++l2w;
*idp=i;
++idp;
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
++idp;
++rn;
}
ubo_l2w->Unmap();
}
vbo_assigns->Unmap();
}
VK_NAMESPACE_END

View File

@@ -0,0 +1,67 @@
#pragma once
#include<hgl/graph/RenderNode.h>
VK_NAMESPACE_BEGIN
// ubo_range大致分为三档:
//
// 16k: Mali-T系列或更早、Mali-G71为16k
//
// 64k: 大部分手机与PC均为64k
//
// >64k: Intel 核显与 PowerVR 为128MBAMD显卡为4GB可视为随显存无上限。
//
// 我们使用uint8类型在vertex input中保存MaterialInstance ID表示范围0-255。
// 所以MaterialInstance结构容量按16k/64k分为两个档次64字节和256字节
// 如果一定要使用超过16K/64K硬件限制的容量有两种办法
// 一、分多次渲染使用UBO Offset偏移UBO数据区。
// 二、使用SSBO但这样会导致性能下降所以不推荐使用。
// 但我们不解决这个问题
// 我们天然要求将材质实例数据分为两个等级同时要求一次渲染不能超过256种材质实例。
// 所以 UBO Range为16k时实例数据不能超过64字节。UBO Range为64k时实例数据不能超过256字节。
struct RenderNode;
class MaterialInstance;
/*
* 渲染节点额外提供的数据
*/
class RenderAssignBuffer
{
private:
GPUDevice *device;
uint node_count; ///<渲染节点数量
DeviceBuffer *ubo_l2w; ///<Local2World数据
uint32_t mi_data_bytes; ///<材质实例数据字节数
uint32_t mi_count; ///<材质实例数量
DeviceBuffer *ubo_mi; ///<材质实例数据
//Assign VBO
VBO *vbo_assigns; ///<RG16UI格式的VertexInputStream,,,,X:L2W ID,Y:MI ID
private:
void Alloc(const uint nc,const uint mc);
void Clear();
public:
VkBuffer GetAssignVBO()const;
void Bind(MaterialInstance *)const;
public:
RenderAssignBuffer(GPUDevice *dev,const uint32_t mi_bytes);
~RenderAssignBuffer(){Clear();}
void WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set);
};//struct RenderAssignBuffer
VK_NAMESPACE_END

View File

@@ -1,209 +0,0 @@
#pragma once
#include<hgl/graph/VKVertexAttribBuffer.h>
VK_NAMESPACE_BEGIN
// ubo_range大致分为三档:
//
// 16k: Mali-T系列或更早、Mali-G71为16k
//
// 64k: 大部分手机与PC均为64k
//
// >64k: Intel 核显与 PowerVR 为128MBAMD显卡为4GB可视为随显存无上限。
//
// 我们使用uint8类型在vertex input中保存MaterialInstance ID表示范围0-255。
// 所以MaterialInstance结构容量按16k/64k分为两个档次64字节和256字节
// 如果一定要使用超过16K/64K硬件限制的容量有两种办法
// 一、分多次渲染使用UBO Offset偏移UBO数据区。
// 二、使用SSBO但这样会导致性能下降所以不推荐使用。
// 但我们不解决这个问题
// 我们天然要求将材质实例数据分为两个等级同时要求一次渲染不能超过256种材质实例。
// 所以 UBO Range为16k时实例数据不能超过64字节。UBO Range为64k时实例数据不能超过256字节。
/*
* 渲染节点额外提供的数据
*/
struct RenderExtraBuffer
{
uint node_count; ///<渲染节点数量
// uint mi_count; ///<材质实例数量
//uint mi_size; ///<单个材质实例数量长度
//DeviceBuffer *mi_data_buffer; ///<材质实例数据UBO/SSBO
//VBO *mi_id;
//VkBuffer mi_id_buffer;
// VBO *bone_id,*bone_weight;
// VkBuffer bone_id_buffer,bone_weight_buffer;
VBO *l2w_vbo[4];
VkBuffer l2w_buffer[4];
//------------------------------------------------------------
//Assign UBO
DeviceBuffer *assigns_l2w;
DeviceBuffer *assigns_mi;
//Assign VBO
VBO *assigns_vbo; ///<RG16UI格式的VertexInputStream,,,,X:L2W ID,Y:MI ID
const uint assigns_vbo_strip=2; ///<Assign VBO的每个节点的字节数
public:
RenderExtraBuffer()
{
hgl_zero(*this);
}
~RenderExtraBuffer()
{
Clear();
}
void ClearNode()
{
SAFE_CLEAR(assigns_l2w);
SAFE_CLEAR(assigns_mi);
SAFE_CLEAR(assigns_vbo);
SAFE_CLEAR(l2w_vbo[0])
SAFE_CLEAR(l2w_vbo[1])
SAFE_CLEAR(l2w_vbo[2])
SAFE_CLEAR(l2w_vbo[3])
node_count=0;
}
//void ClearMI()
//{
// SAFE_CLEAR(mi_id)
// SAFE_CLEAR(mi_data_buffer);
// mi_count=0;
// mi_size=0;
//}
void Clear()
{
ClearNode();
// ClearMI();
// SAFE_CLEAR(bone_id)
// SAFE_CLEAR(bone_weight)
}
void NodeAlloc(GPUDevice *dev,const uint c)
{
ClearNode();
node_count=power_to_2(c);
for(uint i=0;i<4;i++)
{
l2w_vbo[i]=dev->CreateVBO(VF_V4F,node_count);
l2w_buffer[i]=l2w_vbo[i]->GetBuffer();
}
assigns_l2w=dev->CreateUBO(node_count*sizeof(Matrix4f));
//assigns_mi=dev->CreateUBO(node_count*sizeof(uint8));
assigns_vbo=dev->CreateVBO(VF_V1U16,node_count);
}
//void MIAlloc(GPUDevice *dev,const uint c,const uint mis)
//{
// ClearMI();
// if(c<=0||mi_size<=0)return;
//
// mi_count=power_to_2(c);
// mi_size=mis;
// mi_id=dev->CreateVBO(VF_V1U8,mi_count);
// mi_id_buffer=mi_id->GetBuffer();
// mi_data_buffer=dev->CreateUBO(mi_count*mi_size);
//}
void WriteLocalToWorld(RenderNode *render_node,const uint count)
{
RenderNode *rn;
//old l2w in vertex input stream
{
glm::vec4 *tp;
for(uint col=0;col<4;col++)
{
tp=(glm::vec4 *)(l2w_vbo[col]->Map());
rn=render_node;
for(uint i=0;i<count;i++)
{
*tp=rn->local_to_world[col];
++tp;
++rn;
}
l2w_vbo[col]->Unmap();
}
}
//new l2w array in ubo
{
Matrix4f *tp=(hgl::Matrix4f *)(assigns_l2w->Map());
uint16 *idp=(uint16 *)(assigns_vbo->Map());
rn=render_node;
for(uint i=0;i<count;i++)
{
*tp=rn->local_to_world;
++tp;
*idp=i;
++idp;
++rn;
}
assigns_vbo->Unmap();
assigns_l2w->Unmap();
}
}
//void WriteMaterialInstance(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
//{
// //MaterialInstance ID
// {
// uint8 *tp=(uint8 *)(mi_id->Map());
// for(uint i=0;i<count;i++)
// {
// *tp=mi_set.Find(render_node->ri->GetMaterialInstance());
// ++tp;
// ++render_node;
// }
// mi_id->Unmap();
// }
// //MaterialInstance Data
// {
// //const uint count=mi_set.GetCount();
// //uint8 *tp=(uint8 *)(mi_data_buffer->Map());
// //const MaterialInstance **mi=mi_set.GetData();
// //for(uint i=0;i<count;i++)
// //{
// // memcpy(tp,(*mi)->GetData(),mi_size);
//
// // ++mi;
// // tp+=mi_size;
// //}
// //mi_data_buffer->Unmap();
// }
//}
};//struct RenderExtraBuffer
VK_NAMESPACE_END

View File

@@ -1,26 +1,58 @@
# 静态渲染管理
## 建立静态渲染管理的意义是什么?
## 静态渲染的意义是什么?
静态渲染管理中的“静态”并不是指在场景中静止不动的所有物件,也不是指永远不会增加或删除的物件
而是说大部分时间,都会出现在场景中的物件。
静态渲染管理中的“静态”并不是指在场景中静止不动的所有物件,而是说大部分时间都会出现在场景中的物件。它包含地形、花草树木、房屋、常见人物,武器装备等等。如果归划好,可以将绝大部分的物件都划入静态渲染中
它的意义为的是所有添加进管理器的模型原始资源,都会一直存在。与它们本身是否显示在画面中,并无关联。为的是避开对显存资源的动态调配。
在静态渲染管理器中的所有模型,会根据顶点数据格式(Vertex Input Format)分类。每种格式所有模型共用一个大的顶点缓冲对象(Vertex Buffer Object)以达到在渲染时渲染不同模型不会切换VBO的效果并进一步达成一个格式一次Drawcall全部画的极致效果。
在静态渲染管理器中的所有模型,会根据顶点数据格式(Vertex Input Format)分类。每种格式所有模型共用一套超大VBO(Vertex Buffer Object)以达到在渲染时渲染不同模型不会切换VBO的效果并进一步达成一个格式一次Drawcall全部画完”的极致效果。
## 定义
## 材质的定义
1.Material 材质可以简单理解为是Shader的包装。
2.Vertex Input Layout 顶点输入布局指的是在渲染中Material所需的顶点输入数据格式
但需要注意的是VertexInputLayout与Material并无从属关系。
一个Material可能会有多个VertexInputLayout的版本,不同具体格式的数据输入.
多个Material也可能会共用一个VertexInputLayout,比如为某个模型设定的不同画质渲染,它们shader不同但是共用同一套模型数据。
3.Material Instance 材质实例是指同一材质下,不同的参数配置或不同的顶点输入格式。
2.Material Instance 材质实例是指同一材质下,不同的参数配置
## 我们需要做什么?
1.在Shader中建立两个UBO或SSBO
```glsl
//一个用于存所有Local to World矩阵的数组
#define MI_MAX_COUNT (UBORange/sizeof(mat4))
layout(set=?,binding=?) uniform LocalToWorldData
{
mat4 mats[L2W_MAX_COUNT];
}l2w;
```
```glsl
//一个用于存所有MaterialInstance数据的数组
#define MI_MAX_COUNT (UBORange/sizeof(MaterialInstance))
layout(set=?,binding=?) uniform MaterialInstanceData
{
MaterialInstance mi_array[MI_MAX_COUNT];
}mi;
```
2.建立一个RG8UI或RG16UI的Vertex Input Stream,用于保存访问LocalToWorld/MaterialInstance的索引
```glsl
layout(location=?) in uvec2 Assign; //Local To World矩阵ID与材质ID输入数据流
mat4 GetLocalToWorld()
{
return l2w.mats[Assign.x];
}
MaterialInstance GetMaterialInstance()
{
return mi.mi_array[Assign.y];
}
```

View File

@@ -30,6 +30,21 @@ public:
SetRectScope(rs);
}
BufferImageCopy(const Texture2DArray *tex):BufferImageCopy()
{
imageSubresource.aspectMask=tex->GetAspect();
SetRectScope(tex->GetWidth(),tex->GetHeight());
}
template<typename T>
BufferImageCopy(const Texture2DArray *tex,const RectScope2<T> &rs,const uint32_t bl,const uint32_t lc):BufferImageCopy()
{
imageSubresource.aspectMask =tex->GetAspect();
imageSubresource.baseArrayLayer =bl;
imageSubresource.layerCount =lc;
SetRectScope(rs);
}
BufferImageCopy(const TextureCube *tex):BufferImageCopy()
{
imageSubresource.aspectMask=tex->GetAspect();

View File

@@ -0,0 +1,15 @@
#pragma once
#include"BufferImageCopy2D.h"
VK_NAMESPACE_BEGIN
struct CopyBufferToImageInfo
{
VkImage image;
VkBuffer buffer;
VkImageSubresourceRange isr;
const VkBufferImageCopy * bic_list;
uint32_t bic_count;
};
VK_NAMESPACE_END

View File

@@ -1,6 +1,7 @@
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKBuffer.h>
#include"CopyBufferToImage.h"
VK_NAMESPACE_BEGIN
bool GPUDevice::CheckFormatSupport(const VkFormat format,const uint32_t bits,ImageTiling tiling) const
@@ -24,55 +25,78 @@ void GPUDevice::Clear(TextureCreateInfo *tci)
delete tci;
}
bool GPUDevice::CommitTexture(Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t layer_count,VkPipelineStageFlags destinationStage)
bool GPUDevice::CopyBufferToImage(const CopyBufferToImageInfo *info,VkPipelineStageFlags destinationStage)
{
if(!tex||!buf)
if(!info)
return(false);
ImageSubresourceRange subresourceRange(tex->GetAspect(),tex->GetMipLevel(),layer_count);
if(info->bic_count==0)
return(false);
texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
texture_cmd_buf->ImageMemoryBarrier(info->image,
VK_PIPELINE_STAGE_HOST_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT,
0,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
subresourceRange);
info->isr);
texture_cmd_buf->CopyBufferToImage(
buf->GetBuffer(),
tex->GetImage(),
info->buffer,
info->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
count,
buffer_image_copy);
info->bic_count,
info->bic_list);
if(destinationStage==VK_PIPELINE_STAGE_TRANSFER_BIT) //接下来还有一般是给自动生成mipmaps
{
//texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
//texture_cmd_buf->ImageMemoryBarrier(info->image,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_PIPELINE_STAGE_TRANSFER_BIT,
// VK_ACCESS_TRANSFER_WRITE_BIT,
// VK_ACCESS_TRANSFER_READ_BIT,
// VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
// VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
// subresourceRange);
// info->isr);
}
else// if(destinationStage==VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT) //接下来就给fragment shader用了证明是最后一步
{
texture_cmd_buf->ImageMemoryBarrier(tex->GetImage(),
texture_cmd_buf->ImageMemoryBarrier(info->image,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_ACCESS_SHADER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
subresourceRange);
info->isr);
}
return(true);
}
bool GPUDevice::CopyBufferToImage(Texture *tex,DeviceBuffer *buf,const VkBufferImageCopy *buffer_image_copy,const int count,const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags destinationStage)
{
if(!tex||!buf)
return(false);
CopyBufferToImageInfo info;
info.image =tex->GetImage();
info.buffer =buf->GetBuffer();
info.isr.aspectMask =tex->GetAspect();
info.isr.baseMipLevel =0;
info.isr.levelCount =tex->GetMipLevel();
info.isr.baseArrayLayer =base_layer;
info.isr.layerCount =layer_count;
info.bic_list =buffer_image_copy;
info.bic_count =count;
return CopyBufferToImage(&info,destinationStage);
}
bool GPUDevice::SubmitTexture(const VkCommandBuffer *cmd_bufs,const uint32_t count)
{
if(!cmd_bufs||count<=0)

View File

@@ -2,7 +2,8 @@
#include<hgl/graph/VKImageCreateInfo.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKBuffer.h>
#include"BufferImageCopy2D.h"
#include<hgl/graph/VKTexture.h>
#include"CopyBufferToImage.h"
VK_NAMESPACE_BEGIN
void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels,const uint32_t layer_count);
@@ -94,7 +95,7 @@ bool GPUDevice::CommitTexture2D(Texture2D *tex,DeviceBuffer *buf,VkPipelineStage
BufferImageCopy buffer_image_copy(tex);
return CommitTexture(tex,buf,&buffer_image_copy,1,1,destinationStage);
return CopyBufferToImage2D(tex,buf,&buffer_image_copy,destinationStage);
}
bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,DeviceBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes)
@@ -140,7 +141,7 @@ bool GPUDevice::CommitTexture2DMipmaps(Texture2D *tex,DeviceBuffer *buf,const Vk
if(height>1){height>>=1;total_bytes>>=1;}
}
return CommitTexture(tex,buf,buffer_image_copy,miplevel,1,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
return CopyBufferToImage2D(tex,buf,buffer_image_copy,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
bool GPUDevice::ChangeTexture2D(Texture2D *tex,DeviceBuffer *buf,const List<Image2DRegion> &ir_list,VkPipelineStageFlags destinationStage)
@@ -177,7 +178,7 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,DeviceBuffer *buf,const List<Imag
}
texture_cmd_buf->Begin();
bool result=CommitTexture(tex,buf,buffer_image_copy,ir_count,1,destinationStage);
bool result=CopyBufferToImage2D(tex,buf,buffer_image_copy,ir_count,destinationStage);
texture_cmd_buf->End();
SubmitTexture(*texture_cmd_buf);
return result;
@@ -195,7 +196,7 @@ bool GPUDevice::ChangeTexture2D(Texture2D *tex,DeviceBuffer *buf,const RectScope
BufferImageCopy buffer_image_copy(tex,scope);
texture_cmd_buf->Begin();
bool result=CommitTexture(tex,buf,&buffer_image_copy,1,1,destinationStage);
bool result=CopyBufferToImage2D(tex,buf,&buffer_image_copy,1,destinationStage);
texture_cmd_buf->End();
SubmitTexture(*texture_cmd_buf);
return result;

View File

@@ -0,0 +1,246 @@
#include<hgl/graph/VKDevice.h>
#include<hgl/graph/VKImageCreateInfo.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKBuffer.h>
#include<hgl/graph/VKTexture.h>
#include"CopyBufferToImage.h"
VK_NAMESPACE_BEGIN
void GenerateMipmaps(TextureCmdBuffer *texture_cmd_buf,VkImage image,VkImageAspectFlags aspect_mask,VkExtent3D extent,const uint32_t mipLevels,const uint32_t layer_count);
Texture2DArray *GPUDevice::CreateTexture2DArray(TextureData *tex_data)
{
if(!tex_data)
return(nullptr);
return(new Texture2DArray(attr->device,tex_data));
}
Texture2DArray *GPUDevice::CreateTexture2DArray(TextureCreateInfo *tci)
{
if(!tci)return(nullptr);
if(tci->extent.width*tci->extent.height<=0)
{
Clear(tci);
return(nullptr);
}
if(tci->target_mipmaps==0)
tci->target_mipmaps=(tci->origin_mipmaps>1?tci->origin_mipmaps:1);
if(!tci->image)
{
Image2DArrayCreateInfo ici(tci->usage,tci->tiling,tci->format,tci->extent,tci->target_mipmaps);
tci->image=CreateImage(&ici);
if(!tci->image)
{
Clear(tci);
return(nullptr);
}
tci->memory=CreateMemory(tci->image);
}
if(!tci->image_view)
tci->image_view=CreateImageView2DArray(attr->device,tci->format,tci->extent,tci->target_mipmaps,tci->aspect,tci->image);
TextureData *tex_data=new TextureData(tci);
Texture2DArray *tex=CreateTexture2DArray(tex_data);
if(!tex)
{
Clear(tci);
return(nullptr);
}
//我们暂不也不准备支持从文件加载整个texture 2d array所以这里的代码暂时注释掉。仅支持创建空的Texture2d array后一张张2D纹理单独提交
//
//if((!tci->buffer)&&tci->pixels&&tci->total_bytes>0)
// tci->buffer=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,tci->total_bytes,tci->pixels);
//if(tci->buffer)
//{
// texture_cmd_buf->Begin();
// if(tci->target_mipmaps==tci->origin_mipmaps)
// {
// if(tci->target_mipmaps<=1) //本身不含mipmaps但也不要mipmaps
// {
// CommitTexture2DArray(tex,tci->buffer,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
// }
// else //本身有mipmaps数据
// {
// CommitTexture2DMipmapsArray(tex,tci->buffer,tci->extent,tci->mipmap_zero_total_bytes);
// }
// }
// else
// if(tci->origin_mipmaps<=1) //本身不含mipmaps数据,又想要mipmaps
// {
// CommitTexture2DArray(tex,tci->buffer,VK_PIPELINE_STAGE_TRANSFER_BIT);
// GenerateMipmaps(texture_cmd_buf,tex->GetImage(),tex->GetAspect(),tci->extent,tex_data->miplevel,1);
// }
// texture_cmd_buf->End();
// SubmitTexture(*texture_cmd_buf);
// delete tci->buffer;
//}
delete tci; //"delete tci" is correct,please don't use "Clear(tci)"
return tex;
}
Texture2DArray *GPUDevice::CreateTexture2DArray(const uint32_t w,const uint32_t h,const uint32 l,const VkFormat fmt,const bool mipmaps)
{
if(w*h*l<=0)
return(nullptr);
if(!CheckVulkanFormat(fmt))
return(nullptr);
TextureCreateInfo *tci=new TextureCreateInfo(fmt);
tci->extent.width =w;
tci->extent.height =h;
tci->extent.depth =l;
return CreateTexture2DArray(tci);
}
//
//bool GPUDevice::CommitTexture2DArray(Texture2DArray *tex,DeviceBuffer *buf,VkPipelineStageFlags destinationStage)
//{
// if(!tex||!buf)return(false);
//
// BufferImageCopy buffer_image_copy(tex);
//
// return CopyBufferToImageArray(tex,buf,&buffer_image_copy,destinationStage);
//}
//
//bool GPUDevice::CommitTexture2DArrayMipmaps(Texture2DArray *tex,DeviceBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes)
//{
// if(!tex||!buf
// ||extent.width*extent.height<=0)
// return(false);
//
// const uint32_t miplevel=tex->GetMipLevel();
//
// AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(miplevel);
//
// VkDeviceSize offset=0;
// uint32_t level=0;
//
// uint32_t width=extent.width;
// uint32_t height=extent.height;
//
// buffer_image_copy.zero();
//
// for(VkBufferImageCopy &bic:buffer_image_copy)
// {
// bic.bufferOffset = offset;
// bic.bufferRowLength = 0;
// bic.bufferImageHeight = 0;
// bic.imageSubresource.aspectMask = tex->GetAspect();
// bic.imageSubresource.mipLevel = level++;
// bic.imageSubresource.baseArrayLayer = 0;
// bic.imageSubresource.layerCount = 1;
// bic.imageOffset.x = 0;
// bic.imageOffset.y = 0;
// bic.imageOffset.z = 0;
// bic.imageExtent.width = width;
// bic.imageExtent.height= height;
// bic.imageExtent.depth = 1;
//
// if(total_bytes<8)
// offset+=8;
// else
// offset+=total_bytes;
//
// if(width>1){width>>=1;total_bytes>>=1;}
// if(height>1){height>>=1;total_bytes>>=1;}
// }
//
// return CopyBufferToImageArray(tex,buf,buffer_image_copy,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
//}
//
//bool GPUDevice::ChangeTexture2DArray(Texture2DArray *tex,DeviceBuffer *buf,const List<Image2DRegion> &ir_list,const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags destinationStage)
//{
// if(!tex||!buf||ir_list.GetCount()<=0)
// return(false);
//
// const int ir_count=ir_list.GetCount();
// int count=0;
//
// AutoDeleteArray<VkBufferImageCopy> buffer_image_copy(ir_count);
// VkBufferImageCopy *tp=buffer_image_copy;
//
// VkDeviceSize offset=0;
//
// for(const Image2DRegion &sp:ir_list)
// {
// tp->bufferOffset = offset;
// tp->bufferRowLength = 0;
// tp->bufferImageHeight = 0;
// tp->imageSubresource.aspectMask = tex->GetAspect();
// tp->imageSubresource.mipLevel = 0;
// tp->imageSubresource.baseArrayLayer = base_layer;
// tp->imageSubresource.layerCount = layer_count;
// tp->imageOffset.x = sp.left;
// tp->imageOffset.y = sp.top;
// tp->imageOffset.z = 0;
// tp->imageExtent.width = sp.width;
// tp->imageExtent.height= sp.height;
// tp->imageExtent.depth = 1;
//
// offset+=sp.bytes;
// ++tp;
// }
//
// texture_cmd_buf->Begin();
// bool result=CopyBufferToImageArray(tex,buf,buffer_image_copy,ir_count,1,destinationStage);
// texture_cmd_buf->End();
// SubmitTexture(*texture_cmd_buf);
// return result;
//}
bool GPUDevice::ChangeTexture2DArray(Texture2DArray *tex,DeviceBuffer *buf,const RectScope2ui &scope,const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags destinationStage)
{
if(!tex||!buf
||base_layer<0
||layer_count<=0
||scope.GetWidth()<=0
||scope.GetHeight()<=0
||scope.GetRight()>tex->GetWidth()
||scope.GetBottom()>tex->GetHeight())
return(false);
BufferImageCopy buffer_image_copy(tex,scope,base_layer,layer_count);
texture_cmd_buf->Begin();
bool result=CopyBufferToImage(tex,buf,&buffer_image_copy,1,base_layer,layer_count,destinationStage);
texture_cmd_buf->End();
SubmitTexture(*texture_cmd_buf);
return result;
}
bool GPUDevice::ChangeTexture2DArray(Texture2DArray *tex,void *data,const uint32_t size,const RectScope2ui &scope,const uint32_t base_layer,const uint32_t layer_count,VkPipelineStageFlags destinationStage)
{
if(!tex||!data
||size<=0
||base_layer<0
||layer_count<=0
||scope.GetWidth()<=0
||scope.GetHeight()<=0
||scope.GetRight()>tex->GetWidth()
||scope.GetBottom()>tex->GetHeight())
return(false);
DeviceBuffer *buf=CreateBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT,size,data);
bool result=ChangeTexture2DArray(tex,buf,scope,base_layer,layer_count,destinationStage);
delete buf;
return(result);
}
VK_NAMESPACE_END

View File

@@ -90,7 +90,7 @@ bool GPUDevice::CommitTextureCube(TextureCube *tex,DeviceBuffer *buf,const uint3
BufferImageCopy buffer_image_copy(tex);
return CommitTexture(tex,buf,&buffer_image_copy,1,6,destinationStage);
return CopyBufferToImageCube(tex,buf,&buffer_image_copy,destinationStage);
}
bool GPUDevice::CommitTextureCubeMipmaps(TextureCube *tex,DeviceBuffer *buf,const VkExtent3D &extent,uint32_t total_bytes)
@@ -140,7 +140,7 @@ bool GPUDevice::CommitTextureCubeMipmaps(TextureCube *tex,DeviceBuffer *buf,cons
if(height>1){height>>=1;total_bytes>>=1;}
}
return CommitTexture(tex,buf,buffer_image_copy,miplevel,6,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
return CopyBufferToImageCube(tex,buf,buffer_image_copy,miplevel,VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
}
//bool GPUDevice::ChangeTexture2D(Texture2D *tex,DeviceBuffer *buf,const List<Image2DRegion> &ir_list,VkPipelineStageFlags destinationStage)

View File

@@ -0,0 +1,38 @@
#include"VKTextureLoader.h"
#include<hgl/io/FileInputStream.h>
#include<hgl/log/LogInfo.h>
VK_NAMESPACE_BEGIN
//template<> void VkTextureLoader<Texture2DArray,Texture2DArrayLoader>::OnExtent(VkExtent3D &extent)
//{
// extent.width =file_header.width;
// extent.height =file_header.height;
// extent.depth =file_header.layers;
//}
//
//template<> Texture2DArray *VkTextureLoader<Texture2DArray,Texture2DArrayLoader>::OnCreateTexture(TextureCreateInfo *tci)
//{
// return device->CreateTexture2DArray(tci);
//}
bool LoadTexture2DLayerFromFile(GPUDevice *device,Texture2DArray *ta,const uint32_t layer,const OSString &filename,bool auto_mipmaps)
{
//注依然是Texture2D则非Texture2DArray。因为这里LOAD的是2D纹理并不是2DArray纹理
VkTextureLoader<Texture2D,Texture2DLoader> loader(device,auto_mipmaps);
if(!loader.Load(filename))
return(nullptr);
DeviceBuffer *buf=loader.GetBuffer();
if(!buf)
return(false);
RectScope2ui scope;
scope.Width=ta->GetWidth();
scope.Height=ta->GetHeight();
return device->ChangeTexture2DArray(ta,buf,scope,layer,1);
}
VK_NAMESPACE_END

View File

@@ -22,6 +22,6 @@ Texture2D *CreateTexture2DFromFile(GPUDevice *device,const OSString &filename,bo
if(!loader.Load(filename))
return(nullptr);
return loader.GetTexture();
return loader.CreateTexture();
}
VK_NAMESPACE_END

View File

@@ -22,6 +22,6 @@ TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filenam
if(!loader.Load(filename))
return(nullptr);
return loader.GetTexture();
return loader.CreateTexture();
}
VK_NAMESPACE_END

View File

@@ -48,12 +48,21 @@ public:
}
void OnExtent(VkExtent3D &extent);
T *OnCreateTexture(TextureCreateInfo *);
void OnEnd() override
bool OnEnd() override
{
if(!buf)return(false);
buf->Unmap();
return(true);
}
DeviceBuffer *GetBuffer(){return buf;}
T *CreateTexture()
{
TextureCreateInfo *tci=new TextureCreateInfo(format);
VkExtent3D extent;
@@ -82,12 +91,11 @@ public:
SAFE_CLEAR(tex);
tex=OnCreateTexture(tci);
if(tex)
buf=nullptr;
}
if(!tex)
return nullptr;
buf=nullptr;
T *GetTexture()
{
T *result=tex;
tex=nullptr;
return result;

View File

@@ -12,6 +12,8 @@ const VkDeviceSize GPUDevice::GetSSBORange (){return attr->physical_device->Get
bool GPUDevice::CreateBuffer(DeviceBufferData *buf,VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode)
{
if(size<=0)return(false);
BufferCreateInfo buf_info;
buf_info.usage = buf_usage;
@@ -55,6 +57,8 @@ bool GPUDevice::CreateBuffer(DeviceBufferData *buf,VkBufferUsageFlags buf_usage,
VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,SharingMode sharing_mode)
{
if(count==0)return(nullptr);
const uint32_t stride=GetStrideByFormat(format);
if(stride==0)
@@ -75,6 +79,8 @@ VBO *GPUDevice::CreateVBO(VkFormat format,uint32_t count,const void *data,Sharin
IndexBuffer *GPUDevice::CreateIBO(IndexType index_type,uint32_t count,const void *data,SharingMode sharing_mode)
{
if(count==0)return(nullptr);
uint32_t stride;
if(index_type==IndexType::U8 )stride=1;else
@@ -94,6 +100,8 @@ IndexBuffer *GPUDevice::CreateIBO(IndexType index_type,uint32_t count,const void
DeviceBuffer *GPUDevice::CreateBuffer(VkBufferUsageFlags buf_usage,VkDeviceSize range,VkDeviceSize size,const void *data,SharingMode sharing_mode)
{
if(size<=0)return(nullptr);
DeviceBufferData buf;
if(!CreateBuffer(&buf,buf_usage,range,size,data,sharing_mode))

View File

@@ -3,7 +3,12 @@
#include<hgl/graph/VKMaterialDescriptorManager.h>
#include<hgl/graph/VKVertexInput.h>
#include"VKPipelineLayoutData.h"
#include<hgl/type/ActiveMemoryBlockManager.h>
VK_NAMESPACE_BEGIN
void ReleaseVertexInput(VertexInput *vi);
Material::Material(const AnsiString &n)
{
name=n;
@@ -16,21 +21,20 @@ Material::Material(const AnsiString &n)
hgl_zero(mp_array);
mi_data_bytes=0;
mi_max_count=0;
mi_data_manager=nullptr;
}
Material::~Material()
{
SAFE_CLEAR(vertex_input);
SAFE_CLEAR(mi_data_manager);
ReleaseVertexInput(vertex_input);
delete shader_maps; //不用SAFE_CLEAR是因为这个一定会有
SAFE_CLEAR(desc_manager);
SAFE_CLEAR(pipeline_layout_data);
for(int i=0;i<DESCRIPTOR_SET_TYPE_COUNT;i++)
SAFE_CLEAR(mp_array[i]);
mi_data_bytes=0;
mi_max_count=0;
}
const VkPipelineLayout Material::GetPipelineLayout()const
@@ -43,6 +47,11 @@ const bool Material::hasSet(const DescriptorSetType &dst)const
return desc_manager->hasSet(dst);
}
const VIL *Material::GetDefaultVIL()const
{
return vertex_input->GetDefaultVIL();
}
VIL *Material::CreateVIL(const VILConfig *format_map)
{
return vertex_input->CreateVIL(format_map);
@@ -57,4 +66,43 @@ const uint Material::GetVILCount()
{
return vertex_input->GetInstanceCount();
}
bool Material::BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)
{
MaterialParameters *mp=GetMP(type);
if(!mp)
return(false);
if(!mp->BindUBO(name,ubo,dynamic))return(false);
mp->Update();
return(true);
}
bool Material::BindSSBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)
{
MaterialParameters *mp=GetMP(type);
if(!mp)
return(false);
if(!mp->BindSSBO(name,ubo,dynamic))return(false);
mp->Update();
return(true);
}
bool Material::BindImageSampler(const DescriptorSetType &type,const AnsiString &name,Texture *tex,Sampler *sampler)
{
MaterialParameters *mp=GetMP(type);
if(!mp)
return(false);
if(!mp->BindImageSampler(name,tex,sampler))return(false);
mp->Update();
return(true);
}
VK_NAMESPACE_END

View File

@@ -2,6 +2,7 @@
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VKMaterialParameters.h>
#include<hgl/graph/VKShaderModule.h>
#include<hgl/type/ActiveMemoryBlockManager.h>
VK_NAMESPACE_BEGIN
MaterialInstance *Material::CreateMI(const VILConfig *vil_cfg)
@@ -10,52 +11,47 @@ MaterialInstance *Material::CreateMI(const VILConfig *vil_cfg)
if(!vil)return(nullptr);
return(new MaterialInstance(this,vil));
int mi_id=-1;
if(mi_data_manager)
mi_data_manager->GetOrCreate(&mi_id,1);
else
mi_id=-1;
return(new MaterialInstance(this,vil,mi_id));
}
MaterialInstance::MaterialInstance(Material *mtl,VIL *v)
void Material::ReleaseMI(int mi_id)
{
if(mi_id<0||!mi_data_manager)return;
mi_data_manager->Release(&mi_id,1);
}
void *Material::GetMIData(int id)
{
if(!mi_data_manager)
return(nullptr);
return mi_data_manager->GetData(id);
}
void MaterialInstance::WriteMIData(const void *data,const int size)
{
if(!data||size<=0||size>material->GetMIDataBytes())return;
void *tp=GetMIData();
if(tp)
memcpy(tp,data,size);
}
MaterialInstance::MaterialInstance(Material *mtl,VIL *v,const int id)
{
material=mtl;
vil=v;
}
bool MaterialInstance::BindUBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)
{
MaterialParameters *mp=material->GetMP(type);
if(!mp)
return(false);
if(!mp->BindUBO(name,ubo,dynamic))return(false);
mp->Update();
return(true);
}
bool MaterialInstance::BindSSBO(const DescriptorSetType &type,const AnsiString &name,DeviceBuffer *ubo,bool dynamic)
{
MaterialParameters *mp=material->GetMP(type);
if(!mp)
return(false);
if(!mp->BindSSBO(name,ubo,dynamic))return(false);
mp->Update();
return(true);
}
bool MaterialInstance::BindImageSampler(const DescriptorSetType &type,const AnsiString &name,Texture *tex,Sampler *sampler)
{
MaterialParameters *mp=material->GetMP(type);
if(!mp)
return(false);
if(!mp->BindImageSampler(name,tex,sampler))return(false);
mp->Update();
return(true);
mi_id=id;
}
VK_NAMESPACE_END

View File

@@ -56,33 +56,14 @@ Pipeline *RenderPass::CreatePipeline(PipelineData *pd,const ShaderStageCreateInf
return(new Pipeline(device,graphicsPipeline,pd));
}
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
Pipeline *RenderPass::CreatePipeline(Material *mtl,const VIL *vil,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
{
if(!mi)return(nullptr);
Material *mtl=mi->GetMaterial();
const PipelineData *cpd=GetPipelineData(ip);
PipelineData *pd=new PipelineData(cpd);
pd->SetPrim(prim,prim_restart);
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),mi->GetVIL());
if(p)
pipeline_list.Add(p);
return p;
}
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
{
Material *mtl=mi->GetMaterial();
PipelineData *pd=new PipelineData(cpd);
pd->SetPrim(prim,prim_restart);
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),mi->GetVIL());
Pipeline *p=CreatePipeline(pd,mtl->GetStageList(),mtl->GetPipelineLayout(),vil);
if(p)
pipeline_list.Add(p);
@@ -90,6 +71,35 @@ Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cp
return(p);
}
Pipeline *RenderPass::CreatePipeline(Material *mtl,const VIL *vil,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
{
if(!mtl)return(nullptr);
return CreatePipeline(mtl,vil,GetPipelineData(ip),prim,prim_restart);
}
Pipeline *RenderPass::CreatePipeline(Material *mtl,const PipelineData *pd, const Prim &prim,const bool prim_restart)
{
return CreatePipeline(mtl,mtl->GetDefaultVIL(),pd,prim,prim_restart);
}
Pipeline *RenderPass::CreatePipeline(Material *mtl,const InlinePipeline &ip, const Prim &prim,const bool prim_restart)
{
return CreatePipeline(mtl,mtl->GetDefaultVIL(),ip,prim,prim_restart);
}
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const InlinePipeline &ip,const Prim &prim,const bool prim_restart)
{
if(!mi)return(nullptr);
return CreatePipeline(mi->GetMaterial(),mi->GetVIL(),ip,prim,prim_restart);
}
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const PipelineData *cpd,const Prim &prim,const bool prim_restart)
{
return CreatePipeline(mi->GetMaterial(),mi->GetVIL(),cpd,prim,prim_restart);
}
Pipeline *RenderPass::CreatePipeline(MaterialInstance *mi,const OSString &pipeline_filename,const Prim &prim,const bool prim_restart)
{
const PipelineData *pd=GetPipelineData(pipeline_filename);

View File

@@ -147,6 +147,28 @@ Texture2D *RenderResource::LoadTexture2D(const OSString &filename,bool auto_mipm
return tex;
}
Texture2DArray *RenderResource::CreateTexture2DArray(const uint32_t width,const uint32_t height,const uint32_t layer,const VkFormat &fmt,bool auto_mipmaps)
{
Texture2DArray *ta=device->CreateTexture2DArray(width,height,layer,fmt,auto_mipmaps);
if(ta)
Add(ta);
return ta;
}
bool LoadTexture2DLayerFromFile(GPUDevice *device,Texture2DArray *t2d,const uint32_t layer,const OSString &filename,bool auto_mipmaps);
bool RenderResource::LoadTexture2DToArray(Texture2DArray *ta,const uint32_t layer,const OSString &filename)
{
if(!ta)return(false);
if(!LoadTexture2DLayerFromFile(device,ta,layer,filename,false))
return(false);
return(true);
}
TextureCube *CreateTextureCubeFromFile(GPUDevice *device,const OSString &filename,bool auto_mipmaps);
TextureCube *RenderResource::LoadTextureCube(const OSString &filename,bool auto_mipmaps)

View File

@@ -10,6 +10,7 @@
#include<hgl/io/ConstBufferReader.h>
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/shadergen/ShaderDescriptorInfo.h>
#include<hgl/type/ActiveMemoryBlockManager.h>
VK_NAMESPACE_BEGIN
@@ -123,7 +124,7 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
ShaderCreateInfoVertex *vert=mci->GetVS();
if(vert)
mtl->vertex_input=new VertexInput(vert->sdm->GetShaderStageIO().input);
mtl->vertex_input=GetVertexInput(vert->sdm->GetShaderStageIO().input);
}
{
@@ -147,6 +148,11 @@ Material *RenderResource::CreateMaterial(const mtl::MaterialCreateInfo *mci)
mtl->mi_data_bytes =mci->GetMIDataBytes();
mtl->mi_max_count =mci->GetMIMaxCount();
if(mtl->mi_data_bytes>0)
{
mtl->mi_data_manager=new ActiveMemoryBlockManager(mtl->mi_data_bytes);
}
Add(mtl);
material_by_name.Add(mtl_name,mtl);

View File

@@ -0,0 +1,64 @@
#include"Std2DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/mtl/SamplerName.h>
STD_MTL_NAMESPACE_BEGIN
namespace
{
constexpr const char vs_main[]=R"(
void main()
{
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
})";
//一个shader中输出的所有数据会被定义在一个名为Output的结构中。所以编写时要用Output.XXXX来使用。
//而同时这个结构在下一个Shader中以Input名称出现使用时以Input.XXX的形式使用。
constexpr const char fs_main[]=R"(
void main()
{
Color=texture(TextureColor,Input.TexCoord);
})";
class MaterialPureTexture2D:public Std2DMaterial
{
public:
using Std2DMaterial::Std2DMaterial;
~MaterialPureTexture2D()=default;
bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override
{
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
vsc->AddInput(VAT_VEC2,VAN::TexCoord);
vsc->AddOutput(VAT_VEC2,"TexCoord");
vsc->SetMain(vs_main);
return(true);
}
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::Color);
fsc->AddOutput(VAT_VEC4,"Color"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。
fsc->SetMain(fs_main);
return(true);
}
};//class MaterialPureTexture2D:public Std2DMaterial
}//namespace
MaterialCreateInfo *CreatePureTexture2D(const mtl::Material2DCreateConfig *cfg)
{
MaterialPureTexture2D mvc2d(cfg);
return mvc2d.Create();
}
STD_MTL_NAMESPACE_END

View File

@@ -0,0 +1,96 @@
#include"Std2DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/mtl/UBOCommon.h>
#include<hgl/graph/mtl/SamplerName.h>
STD_MTL_NAMESPACE_BEGIN
namespace
{
constexpr const char vs_main[]=R"(
void main()
{
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
})";
//一个shader中输出的所有数据会被定义在一个名为Output的结构中。所以编写时要用Output.XXXX来使用。
//而同时这个结构在下一个Shader中以Input名称出现使用时以Input.XXX的形式使用。
constexpr const char gs_main[]=R"(
void main()
{
vec2 vlt=gl_in[0].gl_Position.xy;
vec2 vrb=gl_in[0].gl_Position.zw;
vec2 tlt=Input[0].TexCoord.xy;
vec2 trb=Input[0].TexCoord.zw;
gl_Position=vec4(vlt, vec2(0,1));Output.TexCoord=tlt; EmitVertex();
gl_Position=vec4(vlt.x, vrb.y, vec2(0,1));Output.TexCoord=vec2(tlt.x,trb.y); EmitVertex();
gl_Position=vec4(vrb.x, vlt.y, vec2(0,1));Output.TexCoord=vec2(trb.x,tlt.y); EmitVertex();
gl_Position=vec4(vrb, vec2(0,1));Output.TexCoord=trb; EmitVertex();
EndPrimitive();
})";
constexpr const char fs_main[]=R"(
void main()
{
Color=texture(TextureColor,Input.TexCoord);
})";
class MaterialRectTexture2D:public Std2DMaterial
{
public:
using Std2DMaterial::Std2DMaterial;
~MaterialRectTexture2D()=default;
bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override
{
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
vsc->AddInput(VAT_VEC4,VAN::TexCoord);
vsc->AddOutput(VAT_VEC4,"TexCoord");
vsc->SetMain(vs_main);
return(true);
}
bool CustomGeometryShader(ShaderCreateInfoGeometry *gsc) override
{
gsc->SetGeom(Prim::Points,Prim::TriangleStrip,4);
gsc->AddOutput(VAT_VEC2,"TexCoord");
gsc->SetMain(gs_main);
return(true);
}
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::Color);
fsc->AddOutput(VAT_VEC4,"Color"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。
fsc->SetMain(fs_main);
return(true);
}
};//class MaterialRectTexture2D:public Std2DMaterial
}//namespace
MaterialCreateInfo *CreateRectTexture2D(mtl::Material2DCreateConfig *cfg)
{
if(!cfg)
return(nullptr);
cfg->shader_stage_flag_bit|=VK_SHADER_STAGE_GEOMETRY_BIT;
MaterialRectTexture2D mvc2d(cfg);
return mvc2d.Create();
}
STD_MTL_NAMESPACE_END

View File

@@ -0,0 +1,113 @@
#include"Std2DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include"common/MFRectPrimitive.h"
#include<hgl/graph/mtl/UBOCommon.h>
#include<hgl/graph/mtl/SamplerName.h>
STD_MTL_NAMESPACE_BEGIN
namespace
{
constexpr const char mi_codes[]="uvec4 id;"; //材质实例代码
constexpr const uint32_t mi_bytes=sizeof(Vector4u); //材质实例数据大小
constexpr const char vs_main[]=R"(
void main()
{
HandoverMI();
Output.TexCoord=TexCoord;
gl_Position=GetPosition2D();
})";
//一个shader中输出的所有数据会被定义在一个名为Output的结构中。所以编写时要用Output.XXXX来使用。
//而同时这个结构在下一个Shader中以Input名称出现使用时以Input.XXX的形式使用。
constexpr const char gs_main[]=R"(
void main()
{
vec2 vlt=gl_in[0].gl_Position.xy;
vec2 vrb=gl_in[0].gl_Position.zw;
vec2 tlt=Input[0].TexCoord.xy;
vec2 trb=Input[0].TexCoord.zw;
HandoverMI();gl_Position=vec4(vlt, vec2(0,1));Output.TexCoord=tlt; EmitVertex();
HandoverMI();gl_Position=vec4(vlt.x, vrb.y, vec2(0,1));Output.TexCoord=vec2(tlt.x,trb.y); EmitVertex();
HandoverMI();gl_Position=vec4(vrb.x, vlt.y, vec2(0,1));Output.TexCoord=vec2(trb.x,tlt.y); EmitVertex();
HandoverMI();gl_Position=vec4(vrb, vec2(0,1));Output.TexCoord=trb; EmitVertex();
EndPrimitive();
})";
constexpr const char fs_main[]=R"(
void main()
{
MaterialInstance mi=GetMI();
Color=texture(TextureColor,vec3(Input.TexCoord,mi.id.x));
})";
class MaterialRectTexture2D:public Std2DMaterial
{
public:
using Std2DMaterial::Std2DMaterial;
~MaterialRectTexture2D()=default;
bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override
{
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
vsc->AddInput(VAT_VEC4,VAN::TexCoord);
vsc->AddOutput(VAT_VEC4,"TexCoord");
vsc->SetMain(vs_main);
return(true);
}
bool CustomGeometryShader(ShaderCreateInfoGeometry *gsc) override
{
gsc->SetGeom(Prim::Points,Prim::TriangleStrip,4);
gsc->AddOutput(VAT_VEC2,"TexCoord");
gsc->SetMain(gs_main);
return(true);
}
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2DArray,mtl::SamplerName::Color);
fsc->AddOutput(VAT_VEC4,"Color"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。
fsc->SetMain(fs_main);
return(true);
}
bool EndCustomShader() override
{
mci->SetMaterialInstance( mi_codes, //材质实例glsl代码
mi_bytes, //材质实例数据大小
VK_SHADER_STAGE_FRAGMENT_BIT); //只在Fragment Shader中使用材质实例最终数据
return(true);
}
};//class MaterialRectTexture2D:public Std2DMaterial
}//namespace
MaterialCreateInfo *CreateRectTexture2DArray(mtl::Material2DCreateConfig *cfg)
{
if(!cfg)
return(nullptr);
cfg->shader_stage_flag_bit|=VK_SHADER_STAGE_GEOMETRY_BIT;
MaterialRectTexture2D mvc2d(cfg);
return mvc2d.Create();
}
STD_MTL_NAMESPACE_END

View File

@@ -3,6 +3,7 @@
#include<hgl/graph/mtl/2d/Material2DCreateConfig.h>
#include<hgl/graph/mtl/UBOCommon.h>
#include"common/MFGetPosition.h"
#include"common/MFRectPrimitive.h"
STD_MTL_NAMESPACE_BEGIN
Std2DMaterial::Std2DMaterial(const Material2DCreateConfig *c)
@@ -16,7 +17,9 @@ bool Std2DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
{
RANGE_CHECK_RETURN_FALSE(cfg->coordinate_system)
vsc->AddInput(VAT_VEC2,VAN::Position);
vsc->AddInput(cfg->position_format,VAN::Position);
const bool is_rect=(cfg->prim==Prim::SolidRectangles||cfg->prim==Prim::WireRectangles);
if(cfg->local_to_world)
{
@@ -24,10 +27,18 @@ bool Std2DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
vsc->AddAssign();
vsc->AddFunction(func::GetPosition2DL2W[size_t(cfg->coordinate_system)]);
if(is_rect)
vsc->AddFunction(func::GetPosition2DRectL2W[size_t(cfg->coordinate_system)]);
else
vsc->AddFunction(func::GetPosition2DL2W[size_t(cfg->coordinate_system)]);
}
else
vsc->AddFunction(func::GetPosition2D[size_t(cfg->coordinate_system)]);
{
if(is_rect)
vsc->AddFunction(func::GetPosition2DRect[size_t(cfg->coordinate_system)]);
else
vsc->AddFunction(func::GetPosition2D[size_t(cfg->coordinate_system)]);
}
if(cfg->coordinate_system==CoordinateSystem2D::Ortho)
{

View File

@@ -0,0 +1,59 @@
#include"Std3DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/3d/Material3DCreateConfig.h>
#include<hgl/graph/mtl/UBOCommon.h>
#include"common/MFGetPosition.h"
#include"common/MFRectPrimitive.h"
STD_MTL_NAMESPACE_BEGIN
Std3DMaterial::Std3DMaterial(const Material3DCreateConfig *c)
{
mci=new MaterialCreateInfo(c);
cfg=c;
}
bool Std3DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
{
vsc->AddInput(cfg->position_format,VAN::Position);
if(cfg->local_to_world)
{
mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS);
vsc->AddAssign();
}
mci->AddUBO(VK_SHADER_STAGE_VERTEX_BIT,
DescriptorSetType::Global,
SBS_ViewportInfo);
return(true);
}
MaterialCreateInfo *Std3DMaterial::Create()
{
if(!BeginCustomShader())
return(nullptr);
if(mci->hasVertex())
if(!CustomVertexShader(mci->GetVS()))
return(nullptr);
if(mci->hasGeometry())
if(!CustomGeometryShader(mci->GetGS()))
return(nullptr);
if(mci->hasFragment())
if(!CustomFragmentShader(mci->GetFS()))
return(nullptr);
if(!EndCustomShader())
return(false);
if(!mci->CreateShader())
return(nullptr);
return(mci);
}
STD_MTL_NAMESPACE_END

View File

@@ -0,0 +1,47 @@
#pragma once
#include<hgl/graph/mtl/StdMaterial.h>
namespace hgl
{
namespace graph
{
struct GPUDeviceAttribute;
class ShaderCreateInfoVertex;
class ShaderCreateInfoGeometry;
class ShaderCreateInfoFragment;
namespace mtl
{
class MaterialCreateInfo;
struct Material3DCreateConfig;
class Std3DMaterial
{
protected:
const Material3DCreateConfig *cfg;
MaterialCreateInfo *mci;
protected:
virtual bool BeginCustomShader(){return true;/*some work before creating shader*/};
virtual bool CustomVertexShader(ShaderCreateInfoVertex *);
virtual bool CustomGeometryShader(ShaderCreateInfoGeometry *){return false;}
virtual bool CustomFragmentShader(ShaderCreateInfoFragment *)=0;
virtual bool EndCustomShader(){return true;/*some work after creating shader*/};
public:
Std3DMaterial(const Material3DCreateConfig *);
virtual ~Std3DMaterial()=default;
virtual MaterialCreateInfo *Create();
};//class Std3DMaterial
}//namespace mtl
}//namespace graph
}//namespace hgl

View File

@@ -37,6 +37,7 @@ SOURCE_GROUP("GLSL Compiler" FILES ${GLSL_COMPILER_SOURCE})
set(STD_MTL_HEADER_PATH ${ROOT_INCLUDE_PATH}/hgl/graph/mtl)
SET(SHADERGEN_COMMON_FILES ${STD_MTL_HEADER_PATH}/UBOCommon.h
${STD_MTL_HEADER_PATH}/SamplerName.h
common/MFCommon.h
common/MFGetPosition.h)
@@ -49,8 +50,19 @@ SET(STD_MTL_2D_HEADER_PATH ${STD_MTL_HEADER_PATH}/2d)
SET(STD_MTL_2D_SOURCE_FILES ${STD_MTL_2D_HEADER_PATH}/Material2DCreateConfig.h
2d/Std2DMaterial.h
2d/Std2DMaterial.cpp
2d/VertexColor2D.cpp
2d/PureColor2D.cpp)
2d/M_VertexColor2D.cpp
2d/M_PureColor2D.cpp
2d/M_PureTexture2D.cpp
2d/M_RectTexture2D.cpp
2d/M_RectTexture2DArray.cpp
)
SET(STD_MTL_3D_HEADER_PATH ${STD_MTL_HEADER_PATH}/3d)
SET(STD_MTL_3D_SOURCE_FILES ${STD_MTL_3D_HEADER_PATH}/Material3DCreateConfig.h
3d/Std3DMaterial.h
3d/Std3DMaterial.cpp
)
SET(STD_MTL_SOURCE ${STD_MTL_HEADER_PATH}/MaterialConfig.h
${STD_MTL_HEADER_PATH}/StdMaterial.h
@@ -59,6 +71,7 @@ SET(STD_MTL_SOURCE ${STD_MTL_HEADER_PATH}/MaterialConfig.h
SOURCE_GROUP("Standard Material" FILES ${STD_MTL_SOURCE})
SOURCE_GROUP("Standard Material\\2D" FILES ${STD_MTL_2D_SOURCE_FILES})
SOURCE_GROUP("Standard Material\\3D" FILES ${STD_MTL_3D_SOURCE_FILES})
add_cm_library(ULRE.ShaderGen "ULRE" ${DESC_INFO_HEADER_FILES}
${DESC_INFO_SOURCE_FILES}
@@ -70,4 +83,5 @@ add_cm_library(ULRE.ShaderGen "ULRE" ${DESC_INFO_HEADER_FILES}
${SHADERGEN_COMMON_FILES}
${STD_MTL_SOURCE}
${STD_MTL_2D_SOURCE_FILES}
${STD_MTL_3D_SOURCE_FILES}
)

View File

@@ -27,10 +27,7 @@ MaterialCreateInfo::MaterialCreateInfo(const MaterialCreateConfig *mc)
}
{
l2w_max_count=ubo_range/sizeof(Matrix4f);
if(l2w_max_count>HGL_U16_MAX)
l2w_max_count=HGL_U16_MAX;
l2w_max_count=hgl_min<uint32_t>(ubo_range/sizeof(Matrix4f),HGL_U16_MAX);
l2w_shader_stage=0;
l2w_ubo=nullptr;
@@ -158,20 +155,15 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
if(data_bytes>0)
mi_codes=glsl_codes;
{
mi_max_count=ubo_range/data_bytes;
if(mi_max_count>HGL_U16_MAX) //我们使用uint16传递材质实例ID所以最大数量为65535。未来如考虑使用更多需综合考虑
mi_max_count=HGL_U16_MAX;
}
mi_max_count=hgl_min<uint32_t>(ubo_range/data_bytes,HGL_U16_MAX);
mdi.AddStruct(MaterialInstanceStruct,mi_codes);
mdi.AddStruct(SBS_MaterialInstanceData);
mdi.AddStruct(SBS_MaterialInstance);
mi_ubo=new UBODescriptor();
mi_ubo->type=SBS_MaterialInstanceData.struct_name;
hgl::strcpy(mi_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstanceData.name);
mi_ubo->type=SBS_MaterialInstance.struct_name;
hgl::strcpy(mi_ubo->name,DESCRIPTOR_NAME_MAX_LENGTH,SBS_MaterialInstance.name);
mi_ubo->stage_flag=shader_stage_flag_bits;
mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,mi_ubo);
@@ -246,10 +238,13 @@ bool MaterialCreateInfo::CreateShader()
if(sc->GetShaderStage()<mi_shader_stage)
{
sc->AddOutput(VAT_UINT,VAN::MaterialInstanceID,Interpolation::Flat);
sc->AddOutput(VAT_UINT,mtl::func::MaterialInstanceID,Interpolation::Flat);
if(sc->GetShaderStage()==VK_SHADER_STAGE_VERTEX_BIT)
sc->AddFunction(mtl::func::HandoverMI_VS);
else
if(sc->GetShaderStage()==VK_SHADER_STAGE_GEOMETRY_BIT)
sc->AddFunction(mtl::func::HandoverMI_GS);
else
sc->AddFunction(mtl::func::HandoverMI);
}

View File

@@ -186,7 +186,11 @@ bool ShaderCreateInfo::ProcInput(ShaderCreateInfo *last_sc)
final_shader+="\nlayout(location=0) in ";
final_shader+=last_output;
final_shader+="Input;\n";
if(shader_stage==VK_SHADER_STAGE_GEOMETRY_BIT)
final_shader+="Input[];\n";
else
final_shader+="Input;\n";
return(true);
}
@@ -308,7 +312,7 @@ bool ShaderCreateInfo::ProcSSBO()
return(false);
}
bool ShaderCreateInfo::ProcConst()
bool ShaderCreateInfo::ProcConstantID()
{
auto const_list=sdm->GetConstList();
@@ -360,7 +364,7 @@ bool ShaderCreateInfo::ProcSampler()
final_shader+=(*sampler)->type;
final_shader+=" ";
final_shader+=(*sampler)->name;
final_shader+="\n";
final_shader+=";\n";
++sampler;
}
@@ -377,6 +381,9 @@ bool ShaderCreateInfo::CreateShader(ShaderCreateInfo *last_sc)
ProcDefine();
if(!ProcLayout())
return(false);
if(!ProcSubpassInput())
return(false);
if(!ProcInput(last_sc))
@@ -390,7 +397,7 @@ bool ShaderCreateInfo::CreateShader(ShaderCreateInfo *last_sc)
return(false);
//if(!ProcSSBO())
//return(false);
if(!ProcConst())
if(!ProcConstantID())
return(false);
if(!ProcSampler())
return(false);

View File

@@ -0,0 +1,36 @@
#include<hgl/shadergen/ShaderCreateInfoGeometry.h>
namespace hgl
{
namespace graph
{
bool ShaderCreateInfoGeometry::SetGeom(const Prim &ip,const Prim &op,const uint32_t mv)
{
if(ip==Prim::Points )input_prim="points";else
if(ip==Prim::Lines )input_prim="lines";else
if(ip==Prim::LinesAdj )input_prim="lines_adjacency";else
if(ip==Prim::Triangles )input_prim="triangles";else
if(ip==Prim::TrianglesAdj )input_prim="triangles_adjacency";else
return(false);
if(op==Prim::Points )output_prim="points";else
if(op==Prim::LineStrip )output_prim="line_strip";else
if(op==Prim::TriangleStrip )output_prim="triangle_strip";else
return(false);
if(mv==0)
return(false);
max_vertices=mv;
return(true);
}
bool ShaderCreateInfoGeometry::ProcLayout()
{
final_shader+="layout("+input_prim+") in;\n"
"layout("+output_prim+", max_vertices = "+AnsiString::numberOf(max_vertices)+") out;\n";
return(true);
}
}//namespace graph
}//namespace hgl

View File

@@ -2,6 +2,7 @@
#include<hgl/shadergen/ShaderDescriptorInfo.h>
#include<hgl/graph/VertexAttrib.h>
#include<hgl/graph/VKShaderStage.h>
#include<hgl/graph/VKRenderAssign.h>
#include"GLSLCompiler.h"
#include"common/MFCommon.h"
@@ -39,9 +40,10 @@ void ShaderCreateInfoVertex::AddJoint()
void ShaderCreateInfoVertex::AddAssign()
{
char name[]="Assign";
AddInput(VAT_UINT,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::Assign);
AddInput( ASSIGN_VAT_FMT,
ASSIGN_VIS_NAME,
VK_VERTEX_INPUT_RATE_INSTANCE,
VertexInputGroup::Assign);
AddFunction(mtl::func::GetLocalToWorld);
}

View File

@@ -14,6 +14,8 @@ mat4 GetLocalToWorld()
}
)";
constexpr const char MaterialInstanceID[]="MaterialInstanceID";
constexpr const char HandoverMI_VS[]=R"(
void HandoverMI()
{
@@ -21,10 +23,17 @@ void HandoverMI()
}
)";
constexpr const char HandoverMI_GS[]=R"(
void HandoverMI()
{
Output.MaterialInstanceID=Input[0].MaterialInstanceID;
}
)";
constexpr const char HandoverMI[]=R"(
void HandoverMI()
{
Output.MaterialInstanceID=Assign.y;
Output.MaterialInstanceID=Input.MaterialInstanceID;
}
)";

View File

@@ -0,0 +1,68 @@
#pragma once
#include<hgl/graph/mtl/StdMaterial.h>
STD_MTL_NAMESPACE_BEGIN
namespace func
{
constexpr const char *GetPosition2DRect[size_t(CoordinateSystem2D::RANGE_SIZE)]=
{
R"(
vec4 GetPosition2D()
{
return Position;
}
)",
R"(
vec4 GetPosition2D()
{
return Position*2-1;
}
)",
R"(
vec4 GetPosition2D()
{
vec4 lt=viewport.ortho_matrix*vec4(Position.xy,0,1);
vec4 rb=viewport.ortho_matrix*vec4(Position.zw,0,1);
return vec4(lt.xy,rb.xy);
}
)"
};
constexpr const char *GetPosition2DRectL2W[size_t(CoordinateSystem2D::RANGE_SIZE)]=
{
R"(
vec4 GetPosition2D()
{
vec4 lt=GetLocalToWorld()*vec4(Position.xy,0,1);
vec4 rb=GetLocalToWorld()*vec4(Position.zw,0,1);
return vec4(lt.xy,rb.xy);
}
)",
R"(
vec4 GetPosition2D()
{
vec4 lt=GetLocalToWorld()*vec4(Position.xy,0,1);
vec4 rb=GetLocalToWorld()*vec4(Position.zw,0,1);
return vec4(lt.xy,rb.xy)*2-1;
}
)",
R"(
vec4 GetPosition2D()
{
vec4 lt=viewport.ortho_matrix*GetLocalToWorld()*vec4(Position.xy,0,1);
vec4 rb=viewport.ortho_matrix*GetLocalToWorld()*vec4(Position.zw,0,1);
return vec4(lt.xy,rb.xy);
}
)"
};
}//namespace func
STD_MTL_NAMESPACE_END