Compare commits
50 Commits
devel_24_L
...
devel_26_T
Author | SHA1 | Date | |
---|---|---|---|
6c7f9ea9d1 | |||
253d113375 | |||
ca1bb80b5f | |||
922fc2661b | |||
e9a8e5bbf2 | |||
bba00534ba | |||
c15fbf8252 | |||
9a7e711658 | |||
65c3d5cad1 | |||
7d9192051a | |||
22099b6b84 | |||
322d24c4ca | |||
5230fbc27f | |||
f901708b6c | |||
2487cb1f36 | |||
7805494ca9 | |||
ac4c97d33a | |||
a87a35b5f8 | |||
d456c2bf92 | |||
12e18b517b | |||
2f00aa8e1e | |||
4e144072e4 | |||
907cb3c852 | |||
eb51df8dd0 | |||
ed9ba3876f | |||
97290ce54c | |||
bebac2284f | |||
d5d6a6bc74 | |||
5559178e7c | |||
f58ce4f98b | |||
5c2f136689 | |||
6820ee8c74 | |||
ddb5a0b77a | |||
69646971ce | |||
e71ec4be85 | |||
dbe2370a44 | |||
00d2677066 | |||
4208e47534 | |||
2dedeaad90 | |||
083600a95f | |||
902dc20340 | |||
164498446a | |||
cef5ad073b | |||
c2279c553d | |||
d959e7988d | |||
202bff5870 | |||
8437d8d561 | |||
714fc3dcb7 | |||
e030738a5f | |||
28b2b53d03 |
2
CMCore
2
CMCore
Submodule CMCore updated: 6a21b387f5...416e96c169
Submodule CMPlatform updated: 2ad618e1ff...5e8b83cce4
Submodule CMSceneGraph updated: 8b585e15eb...2c10960ec3
2
CMUtil
2
CMUtil
Submodule CMUtil updated: ff819d8a60...c0990c52eb
16
example/Basic/CMakeLists.txt
Normal file
16
example/Basic/CMakeLists.txt
Normal 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)
|
@@ -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;
|
@@ -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);
|
@@ -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;
|
@@ -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;
|
@@ -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)
|
||||
|
13
example/Gizmo/CMakeLists.txt
Normal file
13
example/Gizmo/CMakeLists.txt
Normal 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)
|
16
example/Texture/CMakeLists.txt
Normal file
16
example/Texture/CMakeLists.txt
Normal 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)
|
@@ -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
|
||||
|
136
example/Texture/texture_rect.cpp
Normal file
136
example/Texture/texture_rect.cpp
Normal 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;
|
||||
}
|
211
example/Texture/texture_rect_array.cpp
Normal file
211
example/Texture/texture_rect_array.cpp
Normal 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;
|
||||
}
|
@@ -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)
|
||||
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
84
inc/hgl/graph/RenderResourceType.h
Normal file
84
inc/hgl/graph/RenderResourceType.h
Normal 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
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
@@ -92,6 +92,8 @@ public:
|
||||
hgl_zero(*this);
|
||||
|
||||
descriptor_pool=1024;
|
||||
|
||||
geometry_shader=true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);}
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
//{
|
||||
|
@@ -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:
|
||||
|
||||
|
@@ -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
|
||||
|
33
inc/hgl/graph/mtl/3d/Material3DCreateConfig.h
Normal file
33
inc/hgl/graph/mtl/3d/Material3DCreateConfig.h
Normal 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
|
@@ -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
|
||||
|
15
inc/hgl/graph/mtl/SamplerName.h
Normal file
15
inc/hgl/graph/mtl/SamplerName.h
Normal 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
|
@@ -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",
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
@@ -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
|
||||
|
@@ -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++)
|
||||
|
118
src/SceneGraph/RenderAssignBuffer.cpp
Normal file
118
src/SceneGraph/RenderAssignBuffer.cpp
Normal 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
|
67
src/SceneGraph/RenderAssignBuffer.h
Normal file
67
src/SceneGraph/RenderAssignBuffer.h
Normal 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 为128MB,AMD显卡为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
|
@@ -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 为128MB,AMD显卡为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
|
@@ -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];
|
||||
}
|
||||
```
|
||||
|
||||
|
@@ -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();
|
||||
|
15
src/SceneGraph/Vulkan/Texture/CopyBufferToImage.h
Normal file
15
src/SceneGraph/Vulkan/Texture/CopyBufferToImage.h
Normal 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
|
@@ -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)
|
||||
|
@@ -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;
|
||||
|
246
src/SceneGraph/Vulkan/Texture/VKDeviceTexture2DArray.cpp
Normal file
246
src/SceneGraph/Vulkan/Texture/VKDeviceTexture2DArray.cpp
Normal 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
|
@@ -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)
|
||||
|
38
src/SceneGraph/Vulkan/Texture/VKTexture2DArrayLoader.cpp
Normal file
38
src/SceneGraph/Vulkan/Texture/VKTexture2DArrayLoader.cpp
Normal 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
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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))
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
64
src/ShaderGen/2d/M_PureTexture2D.cpp
Normal file
64
src/ShaderGen/2d/M_PureTexture2D.cpp
Normal 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
|
96
src/ShaderGen/2d/M_RectTexture2D.cpp
Normal file
96
src/ShaderGen/2d/M_RectTexture2D.cpp
Normal 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
|
113
src/ShaderGen/2d/M_RectTexture2DArray.cpp
Normal file
113
src/ShaderGen/2d/M_RectTexture2DArray.cpp
Normal 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
|
@@ -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)
|
||||
{
|
||||
|
59
src/ShaderGen/3d/Std3DMaterial.cpp
Normal file
59
src/ShaderGen/3d/Std3DMaterial.cpp
Normal 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
|
47
src/ShaderGen/3d/Std3DMaterial.h
Normal file
47
src/ShaderGen/3d/Std3DMaterial.h
Normal 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
|
@@ -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}
|
||||
)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
)";
|
||||
|
||||
|
68
src/ShaderGen/common/MFRectPrimitive.h
Normal file
68
src/ShaderGen/common/MFRectPrimitive.h
Normal 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
|
Reference in New Issue
Block a user