43 Commits

Author SHA1 Message Date
781e108aa3 added comments 2024-06-12 22:31:25 +08:00
1abe8770d7 removed Std3D/VertexLum2D.mtl 2024-06-12 09:55:50 +08:00
8f9ccc3aa1 removed Std3D/VertexLum2D.mtl 2024-06-12 09:55:08 +08:00
cd01c45980 Merge branch 'devel_31_VDMMergeRender' of http://www.hyzgame.com:3000/hyzboy/ULRE into devel_31_VDMMergeRender 2024-06-12 09:49:57 +08:00
941f5ee6ec fixed comment and layout comment. 2024-06-12 09:49:48 +08:00
66fbe5571e added comments 2024-06-12 08:56:01 +08:00
4fcdd42ce4 fixed RayPicking.cpp sample on newest sdk. 2024-06-12 08:53:54 +08:00
d83f04faab fixed a but that PrimitiveCreater::WriteVAB return error. 2024-06-12 08:53:20 +08:00
b71c912fd5 [WIP] RayPicking.cpp 2024-06-12 02:14:56 +08:00
2efb9c83bf added GetVABMap and GetIBMap in Primitive 2024-06-12 02:07:54 +08:00
7b0a185a45 Moved vab_map_list and ibo_map from PrimitiveCreater to PrimitiveData 2024-06-12 01:48:25 +08:00
0a025f0464 added VKBufferMap::Write function. 2024-06-12 01:46:19 +08:00
7f8fbbd3a0 improved VKBufferMap and added newly IBMap/VABMap 2024-06-12 00:23:09 +08:00
cd4733a491 PlaneGrid use 2d position format instead of 3d. 2024-06-02 20:15:56 +08:00
c1d54628d1 Added Std3D/VertexLum2D.mtl 2024-06-02 20:14:30 +08:00
0da0290fc6 resume vab_offset but don't use it in short time. 2024-06-02 15:27:03 +08:00
01bb4b2153 fixed VABMap 2024-06-02 12:40:17 +08:00
66ef3160e1 used newly VKBufferMap in PrimitiveCreater 2024-06-02 12:16:33 +08:00
16ae849809 added VKBufferMap.cpp/.h 2024-06-01 12:08:49 +08:00
8788b3dd6a Clear zero map_ptr_list in PrimitiveCreater 2024-06-01 12:08:26 +08:00
bba5a660a3 fixed PlaneGrid3D sample 2024-06-01 12:07:34 +08:00
aa853fbdfb fixed 3 samples that are texture_quad, texture_rect and texture_rect_array 2024-05-31 23:17:08 +08:00
c780662ff6 fixed draw without VDM 2024-05-31 23:07:05 +08:00
611a9fe61d fixed draw_triangle_in_NDC sample and other about codes. 2024-05-31 22:04:02 +08:00
90152ca74e add texture in BlinnPhongDirectionLight example. 2024-05-30 21:07:13 +08:00
22868dafab [Important] Indirect Draw Finished....test OK!! 2024-05-30 13:39:16 +08:00
6ce713aed5 finished to stat about IndirectDraw data in MaterialRenderList 2024-05-30 13:14:13 +08:00
ac0d1bee59 added VKIndirectCommandBuffer.cpp and other codes. 2024-05-30 01:58:32 +08:00
bf7c6bdeac preparing VKIndirectCommandBuffer.h 2024-05-30 01:14:27 +08:00
cc80fe7f39 add renderitem sort by vdm 2024-05-29 00:55:12 +08:00
55001843ea added vdm sort 2024-05-28 23:49:28 +08:00
8cdf88e2fd added VDM in Primitive/Renderable/PrimitiveDataBuffer 2024-05-28 23:33:15 +08:00
ca8e36687f OK! Can RUN! full OK!...next step is to create VDMRender in MaterialRenderList 2024-05-28 23:10:50 +08:00
86ff7517d9 [WIP] optimizing VDM Support 2024-05-28 02:21:33 +08:00
742fe201ad rename and layout codes. 2024-05-27 01:42:10 +08:00
8bb97ef2de added comments 2024-05-26 15:55:28 +08:00
9947d46ab8 changed many size/count type why to equal vkCmdDraw/vkCmdDrawIndexed 2024-05-26 15:04:44 +08:00
bf5e401566 [STRONG] merge VDM render OK!!! TEST OK! next step is to support VDM Render and non-VDM Render, recommend is two MaterialRenderList class. 2024-05-26 02:25:49 +08:00
0dcf004f4c renamed to VAB from VBO 2024-05-25 22:57:29 +08:00
8d3cd8d561 remove RenderablePrimitiveCreater.h, fixed auto_instance.cpp/auto_merge_material_instance.cpp examples, can RUN. 2024-05-25 22:47:26 +08:00
6740764f07 create DrawData that it split from VertexInputData 2024-05-25 22:08:01 +08:00
a5e76988c7 resume Assign instead of local2world and materialinstanceId in VertexInputStream 2024-05-25 17:58:39 +08:00
08a348392d added GetVDM() in PrimitiveData classes. 2024-05-25 13:48:15 +08:00
76 changed files with 2087 additions and 1318 deletions

2
CMCore

Submodule CMCore updated: 3d27b60c13...ee2bf2b9b8

View File

@@ -23,7 +23,7 @@ Code
#Fragment
sampler2D TextureColor
sampler2D TextureBaseColor
Output
{
@@ -34,6 +34,6 @@ Code
{
void main()
{
FragColor=texture(TextureColor,Input.TexCoord);
FragColor=texture(TextureBaseColor,Input.TexCoord);
}
}

View File

@@ -52,7 +52,7 @@ Code
#Fragment
sampler2D TextureColor
sampler2D TextureBaseColor
Output
{
@@ -63,6 +63,6 @@ Code
{
void main()
{
FragColor=texture(TextureColor,Input.TexCoord);
FragColor=texture(TextureBaseColor,Input.TexCoord);
}
}

View File

@@ -61,7 +61,7 @@ Code
#Fragment
sampler2DArray TextureColor
sampler2DArray TextureBaseColor
Output
{
@@ -74,6 +74,6 @@ Code
{
MaterialInstance mi=GetMI();
FragColor=texture(TextureColor,vec3(Input.TexCoord,mi.id.x));
FragColor=texture(TextureBaseColor,vec3(Input.TexCoord,mi.id.x));
}
}

View File

@@ -0,0 +1,100 @@
#Material
Name BlinnPhong+HalfLambert shading model only color
Reference https://zhuanlan.zhihu.com/p/442023993
Base Std3D/BlinnPhong
//某些Require并不真的存在.ubo文件写成一行一个是为了方便未来改成带路径的
Require LocalToWorld
Require Camera
define HAVE_SPECULAR off //默认不定义HAVE_SPECULAR
UBO
{
File BlinnPhongSun.ubo //文件名,如果/开头表示从ShaderLibrary根目录开始没有则表示同一目录
Struct BlinnPhongSun //结构名称
Name sun //在代码中的变量名
Stage Fragment //会引用的shader
Set Global //Descriptor Set
}
#MaterialInstance
Length 32
Stage Fragment
Code
{
vec4 Color;
uint tex_id;
}
#VertexInput
vec3 Normal
vec2 TexCoord
#Vertex
Output
{
vec4 Position;
vec3 Normal;
vec2 TexCoord
}
Code
{
void main()
{
Output.Normal =GetNormal();
Output.Position =GetPosition3D();
Output.TexCoord =TexCoord;
HandoverMI();
gl_Position =Output.Position;
}
}
#Fragment
sampler2DArray TextureBaseColor
Output
{
vec4 FragColor;
}
Code
{
#define HAVE_SPECULAR
void main()
{
MaterialInstance mi=GetMI();
vec4 texture_color=texture(TextureBaseColor,vec3(Input.TexCoord,mi.tex_id));
//点乘法线和光照
float intensity=0.5*max(dot(Input.Normal,sun.direction.xyz),0.0)+0.5;
//直接光颜色
vec3 direct_color =intensity*sun.color.rgb*mi.Color.rgb*texture_color.rgb;
#ifndef HAVE_SPECULAR
FragColor=vec4(direct_color,1.0);
#else
vec3 spec_color=vec3(0.0);
if(intensity>0.0)
{
vec3 half_vector=normalize(sun.direction.xyz+normalize(Input.Position.xyz+camera.pos));
float specular=max(dot(half_vector,Input.Normal),0.0);
spec_color=specular*pow(specular,8)*sun.color.rgb;
}
FragColor=vec4(direct_color+spec_color,1.0);
#endif//HAVE_SPECULAR
}
}

View File

@@ -3,7 +3,7 @@
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
@@ -16,6 +16,8 @@ constexpr uint32_t SCREEN_HEIGHT=1024;
constexpr uint32_t VERTEX_COUNT=3;
constexpr uint32_t TRIANGLE_NUMBER=12;
constexpr float position_data[VERTEX_COUNT*2]=
{
0.0, 0.0,
@@ -72,18 +74,28 @@ private:
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,"Triangle",VERTEX_COUNT);
PrimitiveCreater rpc(device,material_instance->GetVIL());
if(!rpc.SetVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVAB(VAN::Color, VF_V4UN8, color_data ))return(false);
rpc.Init("Triangle",VERTEX_COUNT);
render_obj=rpc.Create(material_instance,pipeline);
if(!rpc.WriteVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.WriteVAB(VAN::Color, VF_V4UN8, color_data ))return(false);
render_obj=db->CreateRenderable(&rpc,material_instance,pipeline);
if(!render_obj)
return(false);
for(uint i=0;i<12;i++)
render_root.CreateSubNode(rotate(deg2rad(30*i),Vector3f(0,0,1)),render_obj);
double rad;
Matrix4f mat;
for(uint i=0;i<TRIANGLE_NUMBER;i++)
{
rad=deg2rad<double>((360/TRIANGLE_NUMBER)*i); //这里一定要加<float>或<float>否则结果用int保存会出现问题
mat=rotate(rad,Vector3f(0,0,1));
render_root.CreateSubNode(mat,render_obj);
}
render_root.RefreshMatrix();

View File

@@ -3,7 +3,6 @@
#include"VulkanAppFramework.h"
#include<hgl/math/Math.h>
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/graph/RenderList.h>
#include<hgl/color/Color.h>
@@ -84,18 +83,28 @@ private:
bool InitVBOAndRenderList()
{
RenderablePrimitiveCreater rpc(db,"Triangle",VERTEX_COUNT);
PrimitiveCreater pc(device,material->GetDefaultVIL());
if(!rpc.SetVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!pc.Init("Triangle",VERTEX_COUNT))
return(false);
if(!pc.WriteVAB(VAN::Position, VF_V2F, position_data))
return(false);
Primitive *prim=pc.Create();
if(!prim)
return(false);
db->Add(prim);
for(uint i=0;i<DRAW_OBJECT_COUNT;i++)
{
render_obj[i].r=rpc.Create(render_obj[i].mi,pipeline);
render_obj[i].r=db->CreateRenderable(prim,render_obj[i].mi,pipeline);
if(!render_obj[i].r)
return(false);
render_root.CreateSubNode(rotate(deg2rad(double(360/DRAW_OBJECT_COUNT*i)),Vector3f(0,0,1)),render_obj[i].r);
render_root.CreateSubNode(rotate(deg2rad<double>(double(360/DRAW_OBJECT_COUNT*i)),Vector3f(0,0,1)),render_obj[i].r);
}
render_root.RefreshMatrix();

View File

@@ -6,7 +6,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
using namespace hgl;
@@ -108,16 +108,18 @@ private:
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,"Triangle",VERTEX_COUNT);
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Triangle",VERTEX_COUNT);
#ifdef USE_HALF_FLOAT_POSITION
Float32toFloat16(position_data_hf,position_data_float,VERTEX_COUNT*2);
#endif//USE_HALF_FLOAT_POSITION
if(!rpc.SetVAB(VAN::Position, PositionFormat, position_data))return(false);
if(!rpc.SetVAB(VAN::Color, ColorFormat, color_data ))return(false);
if(!rpc.WriteVAB(VAN::Position, PositionFormat, position_data))return(false);
if(!rpc.WriteVAB(VAN::Color, ColorFormat, color_data ))return(false);
render_obj=rpc.Create(material_instance,pipeline);
render_obj=db->CreateRenderable(&rpc,material_instance,pipeline);
return(render_obj);
}

View File

@@ -5,7 +5,7 @@
#include<hgl/filesystem/FileSystem.h>
#include<hgl/graph/SceneInfo.h>
#include<hgl/graph/VKVertexInputConfig.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
using namespace hgl;
@@ -79,17 +79,19 @@ private:
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,"Triangle",VERTEX_COUNT);
PrimitiveCreater rpc(device,material_instance->GetVIL());
rpc.Init("Triangle",VERTEX_COUNT);
#ifdef USE_ZERO2ONE_COORD //使用0 to 1坐标系
if(!rpc.SetVAB(VAN::Position, VF_V2F, position_data_float ))return(false);
if(!rpc.WriteVAB(VAN::Position, VF_V2F, position_data_float ))return(false);
#else //使用ortho坐标系
if(!rpc.SetVAB(VAN::Position, VF_V2U16, position_data_u16 ))return(false);
if(!rpc.WriteVAB(VAN::Position, VF_V2U16, position_data_u16 ))return(false);
#endif//USE_ZERO2ONE_COORD
if(!rpc.SetVAB(VAN::Color, VF_V4UN8, color_data ))return(false);
if(!rpc.WriteVAB(VAN::Color, VF_V4UN8, color_data ))return(false);
render_obj=rpc.Create(material_instance,pipeline);
render_obj=db->CreateRenderable(&rpc,material_instance,pipeline);
return(true);
}

View File

@@ -1,4 +1,4 @@
// Gizmo 3D Move
// Gizmo 3D Move
#include"VulkanAppFramework.h"
#include<hgl/filesystem/FileSystem.h>
@@ -31,7 +31,7 @@ private:
Material * mtl_vtx_color =nullptr;
MaterialInstance * mi_line =nullptr;
Pipeline * pipeline_vtx_color =nullptr;
Primitive * ro_line =nullptr;
Primitive * prim_line =nullptr;
private:
@@ -103,12 +103,12 @@ private:
}
/**
* д<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
* 写入一个坐标轴的线条数据.
*
* \param pos Ҫд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><EFBFBD>
* \param max_line <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param oa1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param oa2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param pos 要写入数据的指针
* \param max_line 主线条方向
* \param oa1 其它轴1方向
* \param oa2 其它轴2方向
*/
void WriteAxisPosition(Vector3f *pos,const Vector3f &max_line,const Vector3f &oa1,const Vector3f &oa2)
{
@@ -116,15 +116,15 @@ private:
constexpr const float AXIS_MIN_STEP =1;
constexpr const float AXIS_ARROW_SIZE=0.25;
const Vector3f end_pos =max_line*AXIS_LENGTH; ///<<EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>λ<EFBFBD><EFBFBD>
const Vector3f cross_pos=max_line*AXIS_MIN_STEP; ///<<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>
const Vector3f arrow_pos=max_line*(AXIS_LENGTH-AXIS_MIN_STEP); ///<<EFBFBD><EFBFBD>ͷĩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD>λ<EFBFBD><EFBFBD>
const Vector3f end_pos =max_line*AXIS_LENGTH; ///<最终点位置
const Vector3f cross_pos=max_line*AXIS_MIN_STEP; ///<坐标轴尾部交叉线位置
const Vector3f arrow_pos=max_line*(AXIS_LENGTH-AXIS_MIN_STEP); ///<箭头末端在主线上的位置
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//主线
pos[0]=Vector3f(0, 0, 0);
pos[1]=end_pos;
//<EFBFBD>ĸ<EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>
//四根箭头线
pos[2]=end_pos;
pos[3]=arrow_pos-oa1*AXIS_ARROW_SIZE;
@@ -137,7 +137,7 @@ private:
pos[8]=end_pos;
pos[9]=arrow_pos+oa2*AXIS_ARROW_SIZE;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//侧边连接其它轴线
pos[10]=cross_pos;
pos[11]=cross_pos+oa1*AXIS_MIN_STEP;
pos[12]=cross_pos;
@@ -165,8 +165,8 @@ private:
constexpr const uint AXIS_MAX_LINES =7;
constexpr const uint AXIS_MAX_VERTICES =AXIS_MAX_LINES*2*3;
ro_line=db->CreatePrimitive("Line",AXIS_MAX_VERTICES);
if(!ro_line)return(false);
prim_line=db->CreatePrimitive("Line",AXIS_MAX_VERTICES);
if(!prim_line)return(false);
Vector3f position_data[3][AXIS_MAX_LINES*2];
@@ -180,8 +180,8 @@ private:
for(Color4f &c:color_data[1])c=Color4f(0,1,0,1);
for(Color4f &c:color_data[2])c=Color4f(0,0,1,1);
if(!ro_line->Set(VAN::Position, db->CreateVAB(VF_V3F,AXIS_MAX_VERTICES,position_data)))return(false);
if(!ro_line->Set(VAN::Color, db->CreateVAB(VF_V4F,AXIS_MAX_VERTICES,color_data )))return(false);
if(!prim_line->Set(VAN::Position, db->CreateVAB(VF_V3F,AXIS_MAX_VERTICES,position_data)))return(false);
if(!prim_line->Set(VAN::Color, db->CreateVAB(VF_V4F,AXIS_MAX_VERTICES,color_data )))return(false);
}
return(true);
@@ -190,7 +190,7 @@ private:
bool InitScene()
{
Add(prim_plane_grid,mi_plane_grid,pipeline_vtx_lum);
Add(ro_line,mi_line,pipeline_vtx_color);
Add(prim_line,mi_line,pipeline_vtx_color);
camera->pos=Vector3f(32,32,32);
camera_control->SetTarget(Vector3f(0,0,0));

View File

@@ -28,6 +28,7 @@ private:
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",Prim::Lines);
cfg.local_to_world=true;
cfg.position_format=VAT_VEC2;
material=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!material)return(false);
@@ -61,7 +62,9 @@ private:
pgci.lum=0.75;
pgci.sub_lum=1.0;
prim_plane_grid=CreatePlaneGrid(db,material->GetDefaultVIL(),&pgci);
PrimitiveCreater pc(device,material->GetDefaultVIL());
prim_plane_grid=CreatePlaneGrid(&pc,&pgci);
return prim_plane_grid;
}
@@ -98,6 +101,11 @@ private:
public:
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
}
bool Init(uint width,uint height) override
{
if(!SceneAppFramework::Init(width,height))

View File

@@ -9,6 +9,7 @@
#include<hgl/graph/Ray.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VertexDataManager.h>
using namespace hgl;
using namespace hgl::graph;
@@ -32,17 +33,16 @@ class TestApp:public SceneAppFramework
private:
Material * material =nullptr;
Material * mtl_plane_grid =nullptr;
MaterialInstance * mi_plane_grid =nullptr;
MaterialInstance * mi_line =nullptr;
Pipeline * pipeline =nullptr;
Pipeline * pipeline_plane_grid =nullptr;
Primitive * prim_plane_grid =nullptr;
Primitive * ro_line =nullptr;
VAB * vab_pos =nullptr;
Material * mtl_line =nullptr;
MaterialInstance * mi_line =nullptr;
Pipeline * pipeline_line =nullptr;
Primitive * prim_line =nullptr;
VABMap * prim_line_vab_map =nullptr;
Ray ray;
@@ -50,30 +50,46 @@ private:
bool InitMaterialAndPipeline()
{
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",Prim::Lines);
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance2D",Prim::Lines);
cfg.local_to_world=true;
material=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!material)return(false);
{
cfg.mtl_name="VertexLuminance2D"; //注意必须用不同名字,未来改名材质文件名+cfg hash名
cfg.position_format=VAT_VEC2;
mi_plane_grid=db->CreateMaterialInstance(material,nullptr,&white_color);
if(!mi_plane_grid)return(false);
mtl_plane_grid=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_plane_grid)return(false);
mi_line=db->CreateMaterialInstance(material,nullptr,&yellow_color);
if(!mi_line)return(false);
mi_plane_grid=db->CreateMaterialInstance(mtl_plane_grid,nullptr,&white_color);
if(!mi_plane_grid)return(false);
pipeline=CreatePipeline(material,InlinePipeline::Solid3D,Prim::Lines);
pipeline_plane_grid=CreatePipeline(mtl_plane_grid,InlinePipeline::Solid3D,Prim::Lines);
if(!pipeline_plane_grid)return(false);
}
if(!pipeline)
return(false);
{
cfg.mtl_name="VertexLuminance3D"; //注意必须用不同名字,未来改名材质文件名+cfg hash名
cfg.position_format=VAT_VEC3;
mtl_line=db->LoadMaterial("Std3D/VertexLum3D",&cfg);
if(!mtl_line)return(false);
mi_line=db->CreateMaterialInstance(mtl_line,nullptr,&yellow_color);
if(!mi_line)return(false);
pipeline_line=CreatePipeline(mtl_line,InlinePipeline::Solid3D,Prim::Lines);
if(!pipeline_line)
return(false);
}
return(true);
}
Renderable *Add(Primitive *r,MaterialInstance *mi)
Renderable *Add(Primitive *r,MaterialInstance *mi,Pipeline *p)
{
Renderable *ri=db->CreateRenderable(r,mi,pipeline);
Renderable *ri=db->CreateRenderable(r,mi,p);
if(!ri)
{
@@ -91,6 +107,8 @@ private:
using namespace inline_geometry;
{
PrimitiveCreater pc(device,mtl_plane_grid->GetDefaultVIL());
struct PlaneGridCreateInfo pgci;
pgci.grid_size.Set(32,32);
@@ -99,15 +117,21 @@ private:
pgci.lum=0.5;
pgci.sub_lum=0.75;
prim_plane_grid=CreatePlaneGrid(db,material->GetDefaultVIL(),&pgci);
prim_plane_grid=CreatePlaneGrid(&pc,&pgci);
}
{
ro_line=db->CreatePrimitive("Line",2);
if(!ro_line)return(false);
PrimitiveCreater pc(device,mtl_line->GetDefaultVIL());
if(!ro_line->Set(VAN::Position, vab_pos= db->CreateVAB(VF_V3F,2,position_data )))return(false);
if(!ro_line->Set(VAN::Luminance, db->CreateVAB(VF_V1F,2,lumiance_data )))return(false);
if(!pc.Init("Line",2))
return(false);
if(!pc.WriteVAB(VAN::Position, VF_V3F,position_data))return(false);
if(!pc.WriteVAB(VAN::Luminance,VF_V1F,lumiance_data))return(false);
prim_line=pc.Create();
prim_line_vab_map=prim_line->GetVABMap(VAN::Position);
}
return(true);
@@ -115,8 +139,8 @@ private:
bool InitScene()
{
Add(prim_plane_grid,mi_plane_grid);
Add(ro_line,mi_line);
Add(prim_plane_grid,mi_plane_grid,pipeline_plane_grid);
Add(prim_line,mi_line,pipeline_line);
camera->pos=Vector3f(32,32,32);
camera_control->SetTarget(Vector3f(0,0,0));
@@ -130,6 +154,12 @@ private:
public:
~TestApp()
{
SAFE_CLEAR(prim_plane_grid);
SAFE_CLEAR(prim_line);
}
bool Init(uint w,uint h)
{
if(!SceneAppFramework::Init(w,h))
@@ -156,7 +186,8 @@ public:
const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标
vab_pos->Write(&pos,3*sizeof(float)); //更新VAB上这个点的位置
prim_line_vab_map->Write(&pos, //更新VAB上这个点的位置
1); //这里的1代表的数据数量,不是字节数
SceneAppFramework::BuildCommandBuffer(index);
}

View File

@@ -28,12 +28,26 @@ static mtl::blinnphong::SunLight sun_light=
constexpr const COLOR AxisColor[4]=
{
COLOR::Red, //X轴颜色
COLOR::Green, //Y轴颜色
COLOR::Blue, //Z轴颜色
COLOR::White //全局颜色
//COLOR::Red, //X轴颜色
//COLOR::Green, //Y轴颜色
//COLOR::Blue, //Z轴颜色
COLOR::White, //全局颜色
COLOR::GhostWhite,
COLOR::BlanchedAlmond,
COLOR::AntiqueWhite
};
constexpr const os_char *tex_filename[]=
{
OS_TEXT("eucalyptus-cross-versailles.Tex2D"),
OS_TEXT("tints-ashton-green-stretcher.Tex2D"),
OS_TEXT("worn-clay-cobble-in-desert-stretcher.Tex2D"),
OS_TEXT("plain-grey-sheer.Tex2D"),
};
constexpr const size_t TexCount=sizeof(tex_filename)/sizeof(os_char *);
class TestApp:public SceneAppFramework
{
private: //plane grid
@@ -47,6 +61,10 @@ private:
DeviceBuffer * ubo_sun =nullptr;
Texture2DArray * texture =nullptr;
Sampler * sampler =nullptr;
private: //sphere
Material * mtl_blinnphong =nullptr;
@@ -62,6 +80,29 @@ private: //sphere
private:
bool InitTexture()
{
texture=db->CreateTexture2DArray( "SeamlessBackground",
256,256, ///<纹理尺寸
TexCount, ///<纹理层数
PF_BC1_RGBUN, ///<纹理格式
false); ///<是否自动产生mipmaps
if(!texture)return(false);
OSString filename;
for(uint i=0;i<TexCount;i++)
{
filename=filesystem::MergeFilename(OS_TEXT("res/image/seamless"),tex_filename[i]);
if(!db->LoadTexture2DToArray(texture,i,filename))
return(false);
}
return(true);
}
bool InitVertexLumMP()
{
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"VertexLuminance3D",Prim::Lines);
@@ -95,17 +136,34 @@ private:
mtl::Material3DCreateConfig cfg(device->GetDeviceAttribute(),"BlinnPhong3D",Prim::Triangles);
cfg.local_to_world=true;
cfg.material_instance=true;
mtl_blinnphong=db->LoadMaterial("Std3D/BlinnPhong/SunLightPureColor",&cfg);
mtl_blinnphong=db->LoadMaterial("Std3D/BlinnPhong/SunLightPureColorTexture",&cfg);
if(!mtl_blinnphong)return(false);
mtl_blinnphong->BindUBO(DescriptorSetType::Global,"sun",ubo_sun);
mtl_blinnphong->Update();
Color4f mi_data;
sampler=db->CreateSampler();
if(!mtl_blinnphong->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
struct MIData
{
Color4f color;
uint32 tex_id[4];
}mi_data;
constexpr const uint MIDataStride=sizeof(MIData);
for(uint i=0;i<4;i++)
{
mi_data=GetColor4f(AxisColor[i],4);
mi_data.color=GetColor4f(AxisColor[i],4);
mi_data.tex_id[0]=i;
mi_blinnphong[i]=db->CreateMaterialInstance(mtl_blinnphong, //材质
nullptr, //顶点输入配置,这里使用nullptr即代表会使用默认配置那么结果将等同于上面的mtl_blinnphong->GetDefaultVIL()
@@ -176,9 +234,9 @@ private:
{
struct CylinderCreateInfo cci;
cci.halfExtend =4; //圆柱一半高度
cci.halfExtend =1.25; //圆柱一半高度
cci.numberSlices=16; //圆柱底部分割数
cci.radius =0.25f; //圆柱半径
cci.radius =1.25f; //圆柱半径
prim_cylinder=CreateCylinder(pc_blinnphong,&cci);
}
@@ -234,9 +292,12 @@ public:
if(!SceneAppFramework::Init(w,h))
return(false);
if(!InitVertexLumMP())
if(!InitTexture())
return(false);
//if(!InitVertexLumMP())
// return(false);
if(!CreateBlinnPhongUBO())
return(false);

View File

@@ -4,7 +4,7 @@
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
@@ -73,7 +73,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@@ -85,12 +85,14 @@ private:
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,"Quad",VERTEX_COUNT);
PrimitiveCreater rpc(device,material_instance->GetVIL());
if(!rpc.SetVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.SetVAB(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
rpc.Init("Quad",VERTEX_COUNT);
render_obj=rpc.Create(material_instance,pipeline);
if(!rpc.WriteVAB(VAN::Position, VF_V2F, position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord, VF_V2F, tex_coord_data))return(false);
render_obj=db->CreateRenderable(&rpc,material_instance,pipeline);
return(render_obj);
}

View File

@@ -4,7 +4,7 @@
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
@@ -69,7 +69,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@@ -81,12 +81,14 @@ private:
bool InitVBO()
{
RenderablePrimitiveCreater rpc(db,"Rectangle",1);
PrimitiveCreater rpc(device,material_instance->GetVIL());
if(!rpc.SetVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
rpc.Init("Rectangle",1);
render_obj=rpc.Create(material_instance,pipeline);
if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
render_obj=db->CreateRenderable(&rpc,material_instance,pipeline);
return(render_obj);
}

View File

@@ -4,7 +4,7 @@
#include<hgl/graph/VKTexture.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKInlinePipeline.h>
#include<hgl/graph/VKRenderablePrimitiveCreater.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/math/Math.h>
#include<hgl/filesystem/Filename.h>
@@ -56,6 +56,7 @@ private:
Pipeline * pipeline =nullptr;
DeviceBuffer * tex_id_ubo =nullptr;
Primitive * prim_rectangle =nullptr;
struct
{
@@ -108,7 +109,7 @@ private:
sampler=db->CreateSampler();
if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集
mtl::SamplerName::Color, ///<采样器名称
mtl::SamplerName::BaseColor, ///<采样器名称
texture, ///<纹理
sampler)) ///<采样器
return(false);
@@ -128,18 +129,22 @@ private:
bool InitVBOAndRenderList()
{
RenderablePrimitiveCreater rpc(db,"Rectangle",1);
PrimitiveCreater rpc(device,material->GetDefaultVIL());
rpc.Init("Rectangle",1);
position_data[2]=1.0f/float(TexCount);
if(!rpc.SetVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.SetVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false);
if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false);
prim_rectangle=rpc.Create();
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);
render_obj[i].r=db->CreateRenderable(prim_rectangle,render_obj[i].mi,pipeline);
if(!render_obj[i].r)
return(false);
@@ -160,6 +165,7 @@ public:
~TestApp()
{
SAFE_CLEAR(prim_rectangle);
SAFE_CLEAR(render_list);
}

View File

@@ -216,16 +216,14 @@ public:
{
if(!ri)return(false);
const VertexInputData *vid=ri->GetVertexInputData();
cb->Begin();
cb->BindFramebuffer(rp,fb);
cb->SetClearColor(0,clear_color);
cb->BeginRenderPass();
cb->BindPipeline(ri->GetPipeline());
cb->BindDescriptorSets(ri->GetMaterial());
cb->BindVBO(ri);
cb->Draw(vid);
cb->BindDataBuffer(ri->GetDataBuffer());
cb->Draw(ri->GetDataBuffer(),ri->GetRenderData());
cb->EndRenderPass();
cb->End();

View File

@@ -1,10 +1,11 @@
#pragma once
#include<hgl/graph/RenderNode.h>
#include<hgl/graph/VKVBOList.h>
#include<hgl/graph/VKVABList.h>
#include<hgl/type/SortedSets.h>
#include<hgl/graph/VKIndirectCommandBuffer.h>
VK_NAMESPACE_BEGIN
class RenderL2WBuffer;
class RenderMIBuffer;
class RenderAssignBuffer;
/**
* 同一材质的对象渲染列表
@@ -20,42 +21,51 @@ class MaterialRenderList
private:
RenderL2WBuffer *l2w_buffer;
RenderMIBuffer *mi_buffer;
RenderAssignBuffer *assign_buffer;
struct RenderItem
{
uint32_t first;
uint32_t count;
uint32_t first_instance; ///<第一个绘制实例(和instance渲染无关,对应InstanceRate的VAB)
uint32_t instance_count;
Pipeline * pipeline;
MaterialInstance * mi;
const VertexInputData * vid;
Pipeline * pipeline;
MaterialInstance * mi;
const PrimitiveDataBuffer * pdb;
const PrimitiveRenderData * prd;
public:
void Set(Renderable *);
};
MaterialInstanceSets mi_set;
IndirectDrawBuffer *icb_draw;
IndirectDrawIndexedBuffer *icb_draw_indexed;
void ReallocICB();
void WriteICB(VkDrawIndirectCommand *,RenderItem *ri);
void WriteICB(VkDrawIndexedIndirectCommand *,RenderItem *ri);
DataArray<RenderItem> ri_array;
uint ri_count;
VkDeviceSize l2w_buffer_size[4];
void StatMI();
void Stat();
protected:
VBOList * vbo_list;
VABList * vab_list;
Pipeline * last_pipeline;
const VertexInputData * last_vid;
uint last_index;
Pipeline * last_pipeline;
const PrimitiveDataBuffer * last_data_buffer;
const VDM * last_vdm;
const PrimitiveRenderData * last_render_data;
bool Bind(const VertexInputData *,const uint);
int first_indirect_draw_index=-1;
uint indirect_draw_count=0;
bool BindVAB(const PrimitiveDataBuffer *,const uint);
void ProcIndirectRender();
void Render(RenderItem *);
public:

View File

@@ -1,13 +1,13 @@
#pragma once
#include<hgl/graph/VertexAttribDataAccess.h>
#include<hgl/graph/VKBufferMap.h>
#include<hgl/graph/VKShaderModule.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/VKIndexBuffer.h>
VK_NAMESPACE_BEGIN
/**
* 可绘制图元创建器
* 可绘制原始图形创建器
*/
class PrimitiveCreater
{
@@ -23,11 +23,15 @@ protected:
AnsiString prim_name;
PrimitiveData * prim_data;
VkDeviceSize vertices_number; ///<顶点数量
uint32_t vertices_number; ///<顶点数量
VkDeviceSize index_number; ///<索引数量
uint32_t index_number; ///<索引数量
IndexType index_type; ///<索引类型
IBAccess * iba; ///<索引缓冲区
IndexBuffer * ibo; ///<索引缓冲区
protected:
const int InitVAB(const AnsiString &name,const VkFormat format,const void *data); ///<取得顶点属性索引
public:
@@ -35,187 +39,41 @@ public:
PrimitiveCreater(VertexDataManager *);
virtual ~PrimitiveCreater();
virtual bool Init(const AnsiString &name,const VkDeviceSize vertices_count,const VkDeviceSize index_count,IndexType it=IndexType::AUTO); ///<初始化,参数为顶点数量
/**
* 初始化一个原始图形创建
* @parama name 原始图形名称
* @parama vertices_count 顶点数量
* @parama index_count 索引数量
* @parama it 索引类型(注当使用VDM时此值无效)
*/
bool Init(const AnsiString &name,
const uint32_t vertices_count,
const uint32_t index_count=0,IndexType it=IndexType::AUTO);
void Clear(); ///<清除创建器数据
void Clear(); ///<清除创建器数据
public: //顶点缓冲区
const VkDeviceSize GetVertexCount()const{ return vertices_number; } ///<取得顶点数量
const uint32_t GetVertexCount()const{ return vertices_number; } ///<取得顶点数量
VABAccess * AcquireVAB (const AnsiString &name,const VkFormat &format,const void *data=nullptr); ///<请求一个顶点属性数据区
bool WriteVAB (const AnsiString &name,const VkFormat &format,const void *data) ///<直接写入顶点属性数据
{
return AcquireVAB(name,format,data);
}
VABMap * GetVABMap (const AnsiString &name,const VkFormat format=VK_FORMAT_UNDEFINED);
bool WriteVAB (const AnsiString &name,const VkFormat format,const void *data); ///<直接写入顶点属性数据
public: //索引缓冲区
const IndexType GetIndexType()const{return index_type;}
const IndexType GetIndexType()const{return index_type;} ///<取得索引类型
const uint32_t GetIndexCount()const{return index_number;} ///<取得索引数量
void * MapIBO();
void UnmapIBO();
IBMap * GetIBMap();
bool WriteIBO(const void *data,const VkDeviceSize count);
bool WriteIBO(const void *data,const uint32_t count);
template<typename T>
bool WriteIBO(const T *data){return WriteIBO(data,index_number);}
template<typename T>
bool WriteIBO(const T *data){return WriteIBO(data,index_number);}
public: //创建可渲染对象
virtual Primitive * Create(); ///<创建一个可渲染对象,并清除创建器数据
Primitive * Create(); ///<创建一个可渲染对象,并清除创建器数据
};//class PrimitiveCreater
/**
* VAB原生数据访问映射
*/
template<typename T> class VABRawMap
{
VABAccess *vaba;
T *map_ptr;
public:
VABRawMap(PrimitiveCreater *pc,const VkFormat &format,const AnsiString &name)
{
vaba=pc->AcquireVAB(name,format);
if(vaba)
map_ptr=(T *)(vaba->vab->Map(vaba->start,vaba->count));
else
map_ptr=nullptr;
}
~VABRawMap()
{
if(vaba)
vaba->vab->Unmap();
}
const bool IsValid()const{ return vaba; }
operator T *(){ return map_ptr; }
};//template<typename T> class VABRawMap
typedef VABRawMap<int8> VABRawMapi8, VABRawMapByte;
typedef VABRawMap<int16> VABRawMapi16,VABRawMapShort;
typedef VABRawMap<int32> VABRawMapi32,VABRawMapInt;
typedef VABRawMap<uint8> VABRawMapu8, VABRawMapUByte;
typedef VABRawMap<uint16> VABRawMapu16,VABRawMapUShort;
typedef VABRawMap<uint32> VABRawMapu32,VABRawMapUInt;
typedef VABRawMap<float> VABRawMapFloat;
typedef VABRawMap<double> VABRawMapDouble;
/**
* VAB VertexAttribDataAccess数据访问映射
*/
template<typename T> class VABMap
{
VABAccess *vaba;
T *vb;
public:
VABMap(PrimitiveCreater *pc,const AnsiString &name)
{
vaba=pc->AcquireVAB(name,T::GetVulkanFormat(),nullptr);
if(vaba)
{
void *map_ptr=vaba->vab->Map(vaba->start,vaba->count);
vb=T::Create(pc->GetVertexCount(),map_ptr);
vb->Begin();
}
else
{
vb=nullptr;
}
}
~VABMap()
{
if(vaba)
vaba->vab->Unmap();
}
void Restart()
{
if(vb)
vb->Begin();
}
const bool IsValid()const{ return vb; }
T *operator->(){ return vb; }
};//template<typename T> class VABMap
typedef VABMap<VB1i8> VABMap1i8 ,VABMap1b;
typedef VABMap<VB1i16> VABMap1i16,VABMap1s;
typedef VABMap<VB1i32> VABMap1i32,VABMap1i;
typedef VABMap<VB1u8> VABMap1u8 ,VABMap1ub;
typedef VABMap<VB1u16> VABMap1u16,VABMap1us;
typedef VABMap<VB1u32> VABMap1u32,VABMap1ui;
typedef VABMap<VB1f> VABMap1f;
typedef VABMap<VB1d> VABMap1d;
typedef VABMap<VB2i8> VABMap2i8 ,VABMap2b;
typedef VABMap<VB2i16> VABMap2i16,VABMap2s;
typedef VABMap<VB2i32> VABMap2i32,VABMap2i;
typedef VABMap<VB2u8> VABMap2u8 ,VABMap2ub;
typedef VABMap<VB2u16> VABMap2u16,VABMap2us;
typedef VABMap<VB2u32> VABMap2u32,VABMap2ui;
typedef VABMap<VB2f> VABMap2f;
typedef VABMap<VB2d> VABMap2d;
typedef VABMap<VB3i32> VABMap3i32,VABMap3i;
typedef VABMap<VB3u32> VABMap3u32,VABMap3ui;
typedef VABMap<VB3f> VABMap3f;
typedef VABMap<VB3d> VABMap3d;
typedef VABMap<VB4i8> VABMap4i8 ,VABMap4b;
typedef VABMap<VB4i16> VABMap4i16,VABMap4s;
typedef VABMap<VB4i32> VABMap4i32,VABMap4i;
typedef VABMap<VB4u8> VABMap4u8, VABMap4ub;
typedef VABMap<VB4u16> VABMap4u16,VABMap4us;
typedef VABMap<VB4u32> VABMap4u32,VABMap4ui;
typedef VABMap<VB4f> VABMap4f;
typedef VABMap<VB4d> VABMap4d;
/**
* 索引缓冲区映射访问
*/
template<typename T> class IBMap
{
PrimitiveCreater *pc;
T *map_ptr;
public:
IBMap(PrimitiveCreater *c)
{
pc=c;
if(pc)
map_ptr=(T *)(pc->MapIBO());
else
map_ptr=nullptr;
}
~IBMap()
{
if(map_ptr&&pc)
pc->UnmapIBO();
}
const bool IsValid()const{ return map_ptr; }
operator T *(){ return map_ptr; }
};//template<typename T> class IBMap
using IBMapU8=IBMap<uint8>;
using IBMapU16=IBMap<uint16>;
using IBMapU32=IBMap<uint32>;
VK_NAMESPACE_END

View File

@@ -54,32 +54,16 @@ class DeviceMemory;
class DeviceBuffer;
struct DeviceBufferData;
struct VertexInputData;
struct PrimitiveDataBuffer;
struct PrimitiveRenderData;
class VertexAttribBuffer;
using VAB=VertexAttribBuffer;
struct VABAccess
{
VAB *vab;
VkDeviceSize start;
VkDeviceSize count;
public:
CompOperatorMemcmp(const VABAccess &);
};//class VABAccess
class IndexBuffer;
struct IndexBufferAccess
{
IndexBuffer *buffer;
VkDeviceSize start;
VkDeviceSize count;
};
using IBAccess=IndexBufferAccess;
class VABMap;
class IBMap;
class GPUCmdBuffer;
class RenderCmdBuffer;
@@ -123,6 +107,12 @@ class Primitive;
class Renderable;
class VertexDataManager;
using VDM=VertexDataManager;
class IndirectDrawBuffer;
class IndirectDrawIndexedBuffer;
class IndirectDispatchBuffer;
class RenderResource;
enum class SharingMode

View File

@@ -23,6 +23,7 @@ private:
friend class GPUDevice;
friend class VertexAttribBuffer;
friend class IndexBuffer;
template<typename T> friend class IndirectCommandBuffer;
DeviceBuffer(VkDevice d,const DeviceBufferData &b)
{

100
inc/hgl/graph/VKBufferMap.h Normal file
View File

@@ -0,0 +1,100 @@
#pragma once
#include<hgl/graph/VK.h>
#include<hgl/graph/VertexAttribDataAccess.h>
VK_NAMESPACE_BEGIN
template<typename T> class VKBufferMap
{
protected:
T *buffer;
int32_t offset;
uint32_t stride;
uint32_t count;
void *map_ptr;
public:
VKBufferMap()
{
buffer=nullptr;
offset=0;
stride=count=0;
}
virtual ~VKBufferMap()
{
Unmap();
}
void Set(T *buf,const int32_t off,const uint32_t s,const uint32_t c)
{
buffer=buf;
offset=off;
stride=s;
count=c;
map_ptr=nullptr;
}
const int32_t GetOffset ()const{ return offset;}
const uint32_t GetStride ()const{ return stride;}
const uint32_t GetCount ()const{ return count; }
const bool IsValid()const{ return buffer; }
void Clear()
{
Unmap();
buffer=nullptr;
offset=0;
stride=count=0;
}
void *Map()
{
if(map_ptr)
return(map_ptr);
if(!buffer)
return(nullptr);
map_ptr=buffer->Map(offset,count);
return map_ptr;
}
void Unmap()
{
if(buffer&&map_ptr)
{
buffer->Unmap();
map_ptr=nullptr;
}
}
bool Write(const void *data,const uint32_t c)
{
if(!data||c==0||c>count)return(false);
if(!map_ptr)
{
if(!buffer)
return(false);
/*
* 注这里的不管是offset还是c都会走VAB/IndexBuffer的虚拟版本。
* 其中的数据均为单元数据长度而非字节数。
*
* 如果需要传字节数就需要buffer->DeviceBuffer::Write()这样操作
*/
return buffer->Write(data,offset,c);
}
memcpy(map_ptr,data,stride*c);
return(true);
}
};//class VKBufferMap
VK_NAMESPACE_END

View File

@@ -2,7 +2,7 @@
#define HGL_GRAPH_VULKAN_COMMAND_BUFFER_INCLUDE
#include<hgl/graph/VK.h>
#include<hgl/graph/VKVBOList.h>
#include<hgl/graph/VKVABList.h>
#include<hgl/graph/VKPipeline.h>
#include<hgl/graph/VKDescriptorSet.h>
#include<hgl/color/Color4f.h>
@@ -154,25 +154,29 @@ public:
void PushConstants(const void *data,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,0, size,data);}
void PushConstants(const void *data,const uint32_t offset,const uint32_t size) {vkCmdPushConstants(cmd_buf,pipeline_layout,VK_SHADER_STAGE_VERTEX_BIT,offset, size,data);}
void BindVBO(const uint32_t first,const uint32_t count,const VkBuffer *vab,const VkDeviceSize *offsets)
void BindVAB(const uint32_t first,const uint32_t count,const VkBuffer *vab,const VkDeviceSize *offsets)
{
vkCmdBindVertexBuffers(cmd_buf,first,count,vab,offsets);
}
bool BindVBO(VBOList *vbo_list)
bool BindVAB(VABList *vab_list)
{
if(!vbo_list)return(false);
if(!vab_list)return(false);
if(!vbo_list->IsFull())return(false);
if(!vab_list->IsFull())return(false);
vkCmdBindVertexBuffers(cmd_buf,0,vbo_list->binding_count,vbo_list->buffer_list,vbo_list->buffer_offset);
vkCmdBindVertexBuffers(cmd_buf,
0, //first binding
vab_list->vab_count, //binding count
vab_list->vab_list, //buffers
vab_list->vab_offset); //buffer offsets
return(true);
}
// void BindIBO(const IBAccess *);
void BindIBO(IndexBuffer *,const VkDeviceSize byte_offset=0);
bool BindVBO(Renderable *);
bool BindDataBuffer(const PrimitiveDataBuffer *);
void SetViewport (uint32_t first,uint32_t count,const VkViewport *vp) {vkCmdSetViewport(cmd_buf,first,count,vp);}
void SetScissor (uint32_t first,uint32_t count,const VkRect2D *sci) {vkCmdSetScissor(cmd_buf,first,count,sci);}
@@ -191,6 +195,15 @@ public: //draw
void DrawIndexed (const uint32_t index_count ) {vkCmdDrawIndexed(cmd_buf,index_count,1,0,0,0);}
void Draw (const uint32_t vertex_count,const uint32_t instance_count) {vkCmdDraw(cmd_buf,vertex_count,instance_count,0,0);}
void DrawIndexed (const uint32_t index_count ,const uint32_t instance_count) {vkCmdDrawIndexed(cmd_buf,index_count,instance_count,0,0,0);}
void DrawIndexed (const uint32_t index_count ,const uint32_t instance_count,const uint32_t firstIndex,const int32_t vertexOffset,const uint32_t firstInstance)
{
vkCmdDrawIndexed(cmd_buf,
index_count,
instance_count,
firstIndex,
vertexOffset,
firstInstance);
}
// template<typename ...ARGS> void Draw (ARGS...args) {vkCmdDraw(cmd_buf,args...);}
// template<typename ...ARGS> void DrawIndexed (ARGS...args) {vkCmdDrawIndexed(cmd_buf,args...);}
@@ -200,8 +213,7 @@ public: //draw
void DrawIndirect (VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndirectCommand )){return DrawIndirect( buf,0,drawCount,stride);}
void DrawIndexedIndirect(VkBuffer buf, uint32_t drawCount,uint32_t stride=sizeof(VkDrawIndexedIndirectCommand )){return DrawIndexedIndirect( buf,0,drawCount,stride);}
void Draw (const VertexInputData *vid);
void DrawIndexed (const IBAccess *iba,const uint32_t instance_count);
void Draw (const PrimitiveDataBuffer *prb,const PrimitiveRenderData *prd,const uint32_t instance_count=1,const uint32_t first_instance=0);
public: //dynamic state
};//class RenderCmdBuffer:public GPUCmdBuffer

View File

@@ -11,12 +11,12 @@ class DeviceBuffer;
class DescriptorSet
{
VkDevice device;
int binding_count;
int vab_count;
VkDescriptorSet desc_set;
VkPipelineLayout pipeline_layout;
ObjectList<VkDescriptorBufferInfo> buffer_list;
ObjectList<VkDescriptorBufferInfo> vab_list;
ObjectList<VkDescriptorImageInfo> image_list;
List<VkWriteDescriptorSet> wds_list;
@@ -29,7 +29,7 @@ public:
DescriptorSet(VkDevice dev,const int bc,VkPipelineLayout pl,VkDescriptorSet ds)
{
device =dev;
binding_count =bc;
vab_count =bc;
desc_set =ds;
pipeline_layout =pl;
@@ -38,11 +38,11 @@ public:
~DescriptorSet()=default;
const uint32_t GetCount ()const{return binding_count;}
const uint32_t GetCount ()const{return vab_count;}
const VkDescriptorSet GetDescriptorSet ()const{return desc_set;}
const VkPipelineLayout GetPipelineLayout ()const{return pipeline_layout;}
const bool IsReady ()const{return wds_list.GetCount()==binding_count;}
const bool IsReady ()const{return wds_list.GetCount()==vab_count;}
void Clear();

View File

@@ -22,6 +22,9 @@ class TileData;
class TileFont;
class FontSource;
class GPUArrayBuffer;
class IndirectDrawBuffer;
class IndirectDrawIndexedBuffer;
class IndirectDispatchBuffer;
struct CopyBufferToImageInfo;
@@ -149,6 +152,14 @@ public: //Buffer相关
GPUArrayBuffer *CreateArrayInUBO(const VkDeviceSize &uint_size);
GPUArrayBuffer *CreateArrayInSSBO(const VkDeviceSize &uint_size);
public: //间接绘制
bool CreateIndirectCommandBuffer(DeviceBufferData *,const uint32_t cmd_count,const uint32_t cmd_size,SharingMode sm=SharingMode::Exclusive);
IndirectDrawBuffer * CreateIndirectDrawBuffer( const uint32_t cmd_count,SharingMode sm=SharingMode::Exclusive);
IndirectDrawIndexedBuffer * CreateIndirectDrawIndexedBuffer(const uint32_t cmd_count,SharingMode sm=SharingMode::Exclusive);
IndirectDispatchBuffer * CreateIndirectDispatchBuffer( const uint32_t cmd_count,SharingMode sm=SharingMode::Exclusive);
public: //Image
VkImage CreateImage (VkImageCreateInfo *);

View File

@@ -1,50 +1,98 @@
#ifndef HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE
#define HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE
#pragma once
#include<hgl/graph/VKBuffer.h>
#include<hgl/graph/VKBufferMap.h>
namespace hgl
VK_NAMESPACE_BEGIN
class IndexBuffer:public DeviceBuffer
{
namespace graph
IndexType index_type;
uint stride;
uint32_t count;
private:
friend class GPUDevice;
IndexBuffer(VkDevice d,const DeviceBufferData &vb,IndexType it,uint32_t _count):DeviceBuffer(d,vb)
{
class IndexBuffer:public DeviceBuffer
{
IndexType index_type;
uint stride;
uint32_t count;
index_type=it;
count=_count;
private:
if(index_type==IndexType::U16)stride=2;else
if(index_type==IndexType::U32)stride=4;else
if(index_type==IndexType::U8)stride=1;else
stride=0;
}
friend class GPUDevice;
public:
IndexBuffer(VkDevice d,const DeviceBufferData &vb,IndexType it,uint32_t _count):DeviceBuffer(d,vb)
{
index_type=it;
count=_count;
~IndexBuffer()=default;
if(index_type==IndexType::U16)stride=2;else
if(index_type==IndexType::U32)stride=4;else
if(index_type==IndexType::U8)stride=1;else
stride=0;
}
const IndexType GetType ()const{return index_type;}
const uint GetStride ()const{return stride;}
const uint32 GetCount ()const{return count;}
public:
public:
~IndexBuffer()=default;
void * Map (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Map(start*stride,size*stride);}
void Flush (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Flush(start*stride,size*stride); }
void Flush (VkDeviceSize size) override {return DeviceBuffer::Flush(size*stride);}
const IndexType GetType ()const{return index_type;}
const uint GetStride ()const{return stride;}
const uint32 GetCount ()const{return count;}
bool Write (const void *ptr,uint32_t start,uint32_t size) override {return DeviceBuffer::Write(ptr,start*stride,size*stride);}
bool Write (const void *ptr,uint32_t size) override {return DeviceBuffer::Write(ptr,0,size*stride);}
};//class IndexBuffer:public DeviceBuffer
public:
class IBMap:public VKBufferMap<IndexBuffer>
{
public:
void * Map (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Map(start*stride,size*stride);}
void Flush (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Flush(start*stride,size*stride); }
void Flush (VkDeviceSize size) override {return DeviceBuffer::Flush(size*stride);}
using VKBufferMap<IndexBuffer>::VKBufferMap;
virtual ~IBMap()=default;
bool Write (const void *ptr,uint32_t start,uint32_t size) override {return DeviceBuffer::Write(ptr,start*stride,size*stride);}
bool Write (const void *ptr,uint32_t size) override {return DeviceBuffer::Write(ptr,0,size*stride);}
};//class IndexBuffer:public DeviceBuffer
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_VULKAN_INDEX_BUFFER_INCLUDE
const IndexType GetType()const{return buffer->GetType();}
void SetIBO(IndexBuffer *ib,const int32_t index_offset,const uint32_t count)
{
VKBufferMap<IndexBuffer>::Set(ib,index_offset,ib->GetStride(),count);
}
};//class IBMap
/**
* 索引缓冲区数据访问映射
*/
template<typename T> class IBTypeMap
{
IBMap *ib_map;
T *map_ptr;
public:
IBTypeMap(IBMap *ibm)
{
ib_map=ibm;
if(ib_map&&ib_map->GetStride()==sizeof(T))
map_ptr=(T *)(ib_map->Map());
else
map_ptr=nullptr;
}
~IBTypeMap()
{
if(map_ptr)
ib_map->Unmap();
}
const bool IsValid()const{ return map_ptr; }
operator T *(){ return map_ptr; }
T *operator->(){ return map_ptr; }
};//template<typename T> class IBTypeMap
using IBMapU8 =IBTypeMap<uint8>;
using IBMapU16=IBTypeMap<uint16>;
using IBMapU32=IBTypeMap<uint32>;
VK_NAMESPACE_END

View File

@@ -0,0 +1,96 @@
#pragma once
#include<hgl/graph/VKBuffer.h>
VK_NAMESPACE_BEGIN
template<typename T>
class IndirectCommandBuffer:public DeviceBuffer
{
protected:
uint32_t max_count;
public:
const uint32_t GetMaxCount ()const{ return max_count; } ///<取得最大指令数
const uint32_t GetCommandLength()const{ return sizeof(T); } ///<取得单个指令的长度字节数
const VkDeviceSize GetTotalBytes ()const{ return sizeof(T)*max_count; } ///<取得缓冲区总计字节数
private:
friend class GPUDevice;
IndirectCommandBuffer(VkDevice d,const DeviceBufferData &vb,const uint32_t mc):DeviceBuffer(d,vb)
{
max_count=mc;
}
public:
virtual ~IndirectCommandBuffer()=default;
void * Map (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Map(start*sizeof(T),size*sizeof(T));}
T * MapCmd (VkDeviceSize start,VkDeviceSize size) {return (T *)Map(start,size);}
T * MapCmd () {return (T *)Map(0,max_count);}
void Flush (VkDeviceSize start,VkDeviceSize size) override{return DeviceBuffer::Flush(start*sizeof(T),size*sizeof(T));}
void Flush (VkDeviceSize size) override{return DeviceBuffer::Flush(size*sizeof(T));}
bool Write (const void *ptr,uint32_t start,uint32_t size) override{return DeviceBuffer::Write(ptr,start*sizeof(T),size*sizeof(T));}
bool Write (const void *ptr,uint32_t size) override{return DeviceBuffer::Write(ptr,0,size*sizeof(T));}
bool WriteCmd(const T *ptr,uint32_t start,uint32_t size) {return DeviceBuffer::Write(ptr,start*sizeof(T),size*sizeof(T));}
bool WriteCmd(const T *ptr,uint32_t size) {return DeviceBuffer::Write(ptr,0,size*sizeof(T));}
};//class IndirectCommandBuffer:public DeviceBuffer
class IndirectDrawBuffer:public IndirectCommandBuffer<VkDrawIndirectCommand>
{
friend class GPUDevice;
public:
using IndirectCommandBuffer<VkDrawIndirectCommand>::IndirectCommandBuffer;
void Draw(VkCommandBuffer cmd_buf,uint32_t cmd_offset,uint32_t draw_count) const
{
vkCmdDrawIndirect(cmd_buf,
buf.buffer,
cmd_offset*sizeof(VkDrawIndirectCommand),
draw_count,
sizeof(VkDrawIndirectCommand));
}
};//class IndirectDrawBuffer:public IndirectCommandBuffer<VkDrawIndirectCommand>
class IndirectDrawIndexedBuffer:public IndirectCommandBuffer<VkDrawIndexedIndirectCommand>
{
friend class GPUDevice;
public:
using IndirectCommandBuffer<VkDrawIndexedIndirectCommand>::IndirectCommandBuffer;
void DrawIndexed(VkCommandBuffer cmd_buf,uint32_t cmd_offset,uint32_t draw_count) const
{
vkCmdDrawIndexedIndirect(cmd_buf,
buf.buffer,
cmd_offset*sizeof(VkDrawIndexedIndirectCommand),
draw_count,
sizeof(VkDrawIndexedIndirectCommand));
}
};//class IndirectDrawIndexedBuffer:public IndirectCommandBuffer<VkDrawIndexedIndirectCommand>
class IndirectDispatchBuffer:public IndirectCommandBuffer<VkDispatchIndirectCommand>
{
friend class GPUDevice;
public:
using IndirectCommandBuffer<VkDispatchIndirectCommand>::IndirectCommandBuffer;
void Dispatch(VkCommandBuffer cmd_buf,uint32_t offset) const
{
vkCmdDispatchIndirect(cmd_buf,buf.buffer,offset);
}
};//class IndirectDispatchBuffer:public IndirectCommandBuffer<VkDispatchIndirectCommand>
VK_NAMESPACE_END

View File

@@ -6,19 +6,10 @@
#include<hgl/graph/VK.h>
VK_NAMESPACE_BEGIN
/**
* 单一图元数据访问接口<br>
*
* 这个只是单纯的提供原始VAB/IB数据派生为两类
*
* 一类是传统的使用独统的独立VAB的
* 一类是使用VDM的
*
*
*
* WIP: *** 1.将数据全部转移到PrimitiveData完成旧的渲染测试
* 2.改成抽象类将独立VAB的做成一个实现
* 3.实现VDM支持
* 原始图元数据访问接口<br>
* Primitive的存为是为了屏蔽PrimitiveData的初始化之类的访问接口以便于更好的管理和使用
*/
class Primitive
{
@@ -40,10 +31,22 @@ public:
public:
const AnsiString & GetName ()const{ return prim_name; }
const VkDeviceSize GetVertexCount ()const;
const int GetVABCount ()const;
VABAccess * GetVABAccess (const AnsiString &);
IBAccess * GetIBAccess ();
const int GetVABIndex (const AnsiString &name)const;
VAB * GetVAB (const int);
VAB * GetVAB (const AnsiString &name){return GetVAB(GetVABIndex(name));}
const int32_t GetVertexOffset ()const; ///<取得顶点偏移(注意是顶点不是字节)
VABMap * GetVABMap (const int); ///<取得VAB映射器
VABMap * GetVABMap (const AnsiString &name){return GetVABMap(GetVABIndex(name));}
const uint32_t GetIndexCount ()const;
IndexBuffer * GetIBO ();
const uint32_t GetFirstIndex ()const; ///<取得第一个索引
IBMap * GetIBMap (); ///<取得索引缓冲区映射器
VertexDataManager * GetVDM (); ///<取得顶点数据管理器
const AABB & GetBoundingBox ()const{return BoundingBox;}
};//class Primitive

View File

@@ -5,6 +5,7 @@
#include<hgl/graph/VKPipeline.h>
#include<hgl/graph/VKDescriptorSet.h>
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/PrimitiveCreater.h>
#include<hgl/graph/VKBuffer.h>
#include<hgl/graph/VKSampler.h>
#include<hgl/graph/VKTexture.h>
@@ -148,6 +149,7 @@ public: //Material
MaterialInstance * CreateMaterialInstance(const mtl::MaterialCreateInfo *,const VILConfig *vil_cfg=nullptr);
Renderable * CreateRenderable(Primitive *r,MaterialInstance *mi,Pipeline *p);
Renderable * CreateRenderable(PrimitiveCreater *pc,MaterialInstance *mi,Pipeline *p);
Sampler * CreateSampler(VkSamplerCreateInfo *sci=nullptr);
Sampler * CreateSampler(Texture *);

View File

@@ -1,5 +1,4 @@
#ifndef HGL_GRAPH_RENDERABLE_INCLUDE
#define HGL_GRAPH_RENDERABLE_INCLUDE
#pragma once
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/VKPipeline.h>
@@ -9,43 +8,64 @@
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VertexAttrib.h>
VK_NAMESPACE_BEGIN
struct VertexInputData
/**
* 原始图元数据缓冲区<Br>
* 提供在渲染之前的数据绑定信息
*/
struct PrimitiveDataBuffer
{
uint32_t binding_count;
VkBuffer *buffer_list;
VkDeviceSize *buffer_offset;
uint32_t vab_count;
VkBuffer * vab_list;
uint32_t vertex_count;
// 理论上讲每个VAB绑定时都是可以指定byte offsets的。但是随后Draw时又可以指定vertexOffset。
// 在我们支持的两种draw模式中一种是每个模型一批VAB所有VAB的offset都是0。
// 另一种是使用VDM为了批量渲染所有的VAB又必须对齐所以每个VAB单独指定offset也不可行。
const IBAccess *ib_access;
VkDeviceSize * vab_offset; //注意这里的offset是字节偏移不是顶点偏移
IndexBuffer * ibo;
VertexDataManager *vdm; //只是用来区分和比较的,不实际使用
public:
VertexInputData(const uint32_t,const uint32_t,const IBAccess *);
~VertexInputData();
PrimitiveDataBuffer(const uint32_t,IndexBuffer *,VertexDataManager *_v=nullptr);
~PrimitiveDataBuffer();
const bool Comp(const VertexInputData *vid)const
{
if(!vid)return(false);
if(binding_count!=vid->binding_count)return(false);
for(uint32_t i=0;i<binding_count;i++)
{
if(buffer_list[i]!=vid->buffer_list[i])return(false);
if(buffer_offset[i]!=vid->buffer_offset[i])return(false);
}
if(vertex_count!=vid->vertex_count)return(false);
if(ib_access!=vid->ib_access)return(false);
return(true);
}
};//struct VertexInputData
const bool Comp(const PrimitiveDataBuffer *pdb)const;
};//struct PrimitiveDataBuffer
/**
* 可渲染对象<br>
* 原始图元渲染数据<Br>
* 提供在渲染时的数据
*/
struct PrimitiveRenderData
{
//因为要VAB是流式访问所以我们这个结构会被用做排序依据
//也因此把vertex_offset放在最前面
int32_t vertex_offset; //注意这里的offset是相对于vertex的代表第几个顶点不是字节偏移
uint32_t first_index;
uint32_t vertex_count;
uint32_t index_count;
public:
PrimitiveRenderData(const uint32_t vc,const uint32_t ic,const int32_t vo=0,const uint32_t fi=0)
{
vertex_count =vc;
index_count =ic;
vertex_offset =vo;
first_index =fi;
}
CompOperatorMemcmp(const PrimitiveRenderData &);
CompOperatorMemcmpPointer(PrimitiveRenderData);
};
/**
* 原始可渲染对象(即仅一个模型一个材质)
*/
class Renderable ///可渲染对象实例
{
@@ -53,17 +73,24 @@ class Renderable
MaterialInstance * mat_inst;
Primitive * primitive;
VertexInputData * vertex_input;
PrimitiveDataBuffer * primitive_data_buffer;
PrimitiveRenderData * primitive_render_data;
private:
friend Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *);
Renderable(Primitive *,MaterialInstance *,Pipeline *,VertexInputData *);
Renderable(Primitive *,MaterialInstance *,Pipeline *,PrimitiveDataBuffer *,PrimitiveRenderData *);
public:
virtual ~Renderable();
virtual ~Renderable()
{
//需要在这里添加删除pipeline/desc_sets/primitive引用计数的代码
SAFE_CLEAR(primitive_data_buffer);
SAFE_CLEAR(primitive_render_data);
}
void UpdatePipeline (Pipeline *p){pipeline=p;}
@@ -74,9 +101,9 @@ public:
Primitive * GetPrimitive (){return primitive;}
const AABB & GetBoundingBox ()const{return primitive->GetBoundingBox();}
const VertexInputData * GetVertexInputData ()const{return vertex_input;}
const PrimitiveDataBuffer *GetDataBuffer ()const{return primitive_data_buffer;}
const PrimitiveRenderData *GetRenderData ()const{return primitive_render_data;}
};//class Renderable
Renderable *CreateRenderable(Primitive *,MaterialInstance *,Pipeline *);
VK_NAMESPACE_END
#endif//HGL_GRAPH_RENDERABLE_INCLUDE

View File

@@ -1,56 +0,0 @@
#ifndef HGL_VK_RENDERABLE_PRIMITIVE_CREATER_INCLUDE
#define HGL_VK_RENDERABLE_PRIMITIVE_CREATER_INCLUDE
#include<hgl/graph/VKRenderResource.h>
VK_NAMESPACE_BEGIN
/**
* 可绘制图元创建器
*/
class RenderablePrimitiveCreater
{
RenderResource *rr;
VkDeviceSize vertex_count;
Primitive *prim;
public:
RenderablePrimitiveCreater(RenderResource *_rr,const AnsiString &name,VkDeviceSize vc)
{
rr=_rr;
vertex_count=vc;
prim=rr->CreatePrimitive(name,vertex_count);
}
VAB *SetVAB(const AnsiString &name,const VkFormat &fmt,const void *buf)
{
VAB *vab=rr->CreateVAB(fmt,vertex_count,buf);
if(!vab)
return(nullptr);
prim->SetVAB(name,vab);
return(vab);
}
IndexBuffer *SetIndex(const IndexType &it,const void *buf,const VkDeviceSize index_count)
{
IndexBuffer *ibo=rr->CreateIBO(it,index_count,buf);
if(!ibo)
return(nullptr);
prim->SetIndex(ibo,0,index_count);
return(ibo);
}
Renderable *Create(MaterialInstance *mi,Pipeline *p)
{
return rr->CreateRenderable(prim,mi,p);
}
};//class RenderablePrimitiveCreater
VK_NAMESPACE_END
#endif // HGL_VK_RENDERABLE_PRIMITIVE_CREATER_INCLUDE

61
inc/hgl/graph/VKVABList.h Normal file
View File

@@ -0,0 +1,61 @@
#pragma once
VK_NAMESPACE_BEGIN
class VABList
{
uint32_t vab_count;
VkBuffer *vab_list;
VkDeviceSize *vab_offset;
uint32_t write_count;
friend class RenderCmdBuffer;
public:
VABList(const uint32 bc)
{
vab_count=bc;
vab_list=new VkBuffer[vab_count];
vab_offset=new VkDeviceSize[vab_count];
write_count=0;
}
~VABList()
{
delete[] vab_offset;
delete[] vab_list;
}
void Restart()
{
write_count=0;
}
const bool IsFull()const
{
return write_count>=vab_count;
}
void Add(const VkBuffer buf,const VkDeviceSize offset)
{
vab_list[write_count]=buf;
vab_offset[write_count]=offset;
++write_count;
}
void Add(const VkBuffer *buf,const VkDeviceSize *offset,const uint32_t count)
{
hgl_cpy(vab_list +write_count,buf, count);
if(offset)
hgl_cpy(vab_offset+write_count,offset,count);
else
hgl_set<VkDeviceSize>(vab_offset+write_count,VkDeviceSize(0),count);
write_count+=count;
}
};//class VABList
VK_NAMESPACE_END

View File

@@ -1,57 +0,0 @@
#pragma once
VK_NAMESPACE_BEGIN
class VBOList
{
uint32_t binding_count;
VkBuffer *buffer_list;
VkDeviceSize *buffer_offset;
uint32_t write_count;
friend class RenderCmdBuffer;
public:
VBOList(const uint32 bc)
{
binding_count=bc;
buffer_list=new VkBuffer[binding_count];
buffer_offset=new VkDeviceSize[binding_count];
write_count=0;
}
~VBOList()
{
delete[] buffer_offset;
delete[] buffer_list;
}
void Restart()
{
write_count=0;
}
const bool IsFull()const
{
return write_count>=binding_count;
}
void Add(const VkBuffer buf,const VkDeviceSize offset)
{
buffer_list[write_count]=buf;
buffer_offset[write_count]=offset;
++write_count;
}
void Add(const VkBuffer *buf,const VkDeviceSize *offset,const uint32_t count)
{
hgl_cpy(buffer_list +write_count,buf, count);
hgl_cpy(buffer_offset+write_count,offset,count);
write_count+=count;
}
};//class VBOList
VK_NAMESPACE_END

View File

@@ -1,50 +1,248 @@
#ifndef HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE
#define HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE
#pragma once
#include<hgl/graph/VKBuffer.h>
#include<hgl/graph/VKBufferMap.h>
namespace hgl
VK_NAMESPACE_BEGIN
class VertexAttribBuffer:public DeviceBuffer
{
namespace graph
VkFormat format; ///<数据格式
uint32_t stride; ///<单个数据字节数
uint32_t count; ///<数据数量
private:
friend class GPUDevice;
VertexAttribBuffer(VkDevice d,const DeviceBufferData &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):DeviceBuffer(d,vb)
{
class VertexAttribBuffer:public DeviceBuffer
format=fmt;
stride=_stride;
count=_count;
}
public:
~VertexAttribBuffer()=default;
const VkFormat GetFormat()const { return format; }
const uint32_t GetStride()const { return stride; }
const uint32_t GetCount ()const { return count; }
const VkDeviceSize GetTotalBytes()const { return stride*count; }
public:
void * Map (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Map(start*stride,size*stride);}
void Flush (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Flush(start*stride,size*stride);}
void Flush (VkDeviceSize size) override {return DeviceBuffer::Flush(size*stride);}
bool Write (const void *ptr,uint32_t start,uint32_t size) override {return DeviceBuffer::Write(ptr,start*stride,size*stride);}
bool Write (const void *ptr,uint32_t size) override {return DeviceBuffer::Write(ptr,0,size*stride);}
};//class VertexAttribBuffer:public DeviceBuffer
using VAB=VertexAttribBuffer;
class VABMap:public VKBufferMap<VAB>
{
public:
using VKBufferMap<VAB>::VKBufferMap;
virtual ~VABMap()=default;
const VkFormat GetFormat()const { return buffer->GetFormat(); }
void SetVAB(VAB *vab,const VkDeviceSize off,const uint32_t count)
{
VKBufferMap<VAB>::Set(vab,off,vab->GetStride(),count);
}
};//class VABMap
/**
* 顶点属性缓冲区原生数据访问映射
*/
template<typename T> class VABRawMap
{
VABMap *vab_map;
T *map_ptr;
public:
VABRawMap(VABMap *map,const VkFormat check_format=VK_FORMAT_UNDEFINED,bool now_map=true)
{
vab_map=map;
map_ptr=nullptr;
if(vab_map)
{
VkFormat format; ///<数据格式
uint32_t stride; ///<单个数据字节数
uint32_t count; ///<数据数量
private:
friend class GPUDevice;
VertexAttribBuffer(VkDevice d,const DeviceBufferData &vb,VkFormat fmt,uint32_t _stride,uint32_t _count):DeviceBuffer(d,vb)
if(check_format==VK_FORMAT_UNDEFINED
||check_format==vab_map->GetFormat())
{
format=fmt;
stride=_stride;
count=_count;
if(now_map)
map_ptr=(T *)(vab_map->Map());
}
else
{
vab_map=nullptr;
}
}
}
public:
~VABRawMap()
{
if(map_ptr)
vab_map->Unmap();
}
~VertexAttribBuffer()=default;
const bool IsValid()const{ return vab_map?vab_map->IsValid():false; }
const VkFormat GetFormat()const { return format; }
const uint32_t GetStride()const { return stride; }
const uint32_t GetCount ()const { return count; }
T *Map()
{
if(!vab_map)
return(nullptr);
const VkDeviceSize GetBytes()const { return stride*count; }
if(!map_ptr)
map_ptr=(T *)(vab_map->Map());
public:
return map_ptr;
}
void * Map (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Map(start*stride,size*stride);}
void Flush (VkDeviceSize start,VkDeviceSize size) override {return DeviceBuffer::Flush(start*stride,size*stride); }
void Flush (VkDeviceSize size) override {return DeviceBuffer::Flush(size*stride);}
void Unmap()
{
if(vab_map)
{
if(map_ptr)
vab_map->Unmap();
}
}
bool Write (const void *ptr,uint32_t start,uint32_t size) override {return DeviceBuffer::Write(ptr,start*stride,size*stride);}
bool Write (const void *ptr,uint32_t size) override {return DeviceBuffer::Write(ptr,0,size*stride);}
};//class VertexAttribBuffer:public DeviceBuffer
operator T *(){ return map_ptr; }
T *operator->(){ return map_ptr; }
};//template<typename T> class VABRawMap
using VAB=VertexAttribBuffer;
}//namespace graph
}//namespace hgl
#endif//HGL_GRAPH_VULKAN_VERTEX_ATTRIB_BUFFER_INCLUDE
typedef VABRawMap<int8> VABMapI8, VABMapByte;
typedef VABRawMap<int16> VABMapI16, VABMapShort;
typedef VABRawMap<int32> VABMapI32, VABMapInt;
typedef VABRawMap<uint8> VABMapU8, VABMapUByte;
typedef VABRawMap<uint16> VABMapU16, VABMapUShort;
typedef VABRawMap<uint32> VABMapU32, VABMapUInt;
typedef VABRawMap<float> VABMapFloat;
typedef VABRawMap<double> VABMapDouble;
/**
* 顶点属性缓冲区数据访问映射
*/
template<typename T> class VABFormatMap
{
VABMap *vab_map;
T *map_ptr;
public:
VABFormatMap(VABMap *map,bool now_map=true)
{
vab_map=map;
if(vab_map&&vab_map->GetFormat()==T::GetVulkanFormat())
{
if(now_map)
{
map_ptr=T::Create(vab_map->GetCount(),vab_map->Map());
map_ptr->Begin();
}
else
{
map_ptr=T::Create(vab_map->GetCount(),nullptr);
}
}
else
map_ptr=nullptr;
}
~VABFormatMap()
{
if(map_ptr)
{
vab_map->Unmap();
delete map_ptr;
}
}
const bool IsValid()const{ return map_ptr?map_ptr->IsValid():false; }
T *Map()
{
if(!vab_map)
return(nullptr);
if(!map_ptr)
{
map_ptr=T::Create(vab_map->GetCount(),vab_map->Map());
}
else
{
if(!map_ptr->IsValid())
map_ptr->SetData(vab_map->Map());
}
map_ptr->Begin();
return map_ptr;
}
void Unmap()
{
if(vab_map)
{
if(map_ptr&&map_ptr->IsValid())
{
vab_map->Unmap();
map_ptr->SetData(nullptr);
}
}
}
void Restart()
{
return Map();
}
T *operator->()
{
return map_ptr;
}
};//template<typename T> class VABFormatMap
typedef VABFormatMap<VB1i8> VABMap1i8 ,VABMap1b;
typedef VABFormatMap<VB1i16> VABMap1i16,VABMap1s;
typedef VABFormatMap<VB1i32> VABMap1i32,VABMap1i;
typedef VABFormatMap<VB1u8> VABMap1u8 ,VABMap1ub;
typedef VABFormatMap<VB1u16> VABMap1u16,VABMap1us;
typedef VABFormatMap<VB1u32> VABMap1u32,VABMap1ui;
typedef VABFormatMap<VB1f> VABMap1f;
typedef VABFormatMap<VB1d> VABMap1d;
typedef VABFormatMap<VB2i8> VABMap2i8 ,VABMap2b;
typedef VABFormatMap<VB2i16> VABMap2i16,VABMap2s;
typedef VABFormatMap<VB2i32> VABMap2i32,VABMap2i;
typedef VABFormatMap<VB2u8> VABMap2u8 ,VABMap2ub;
typedef VABFormatMap<VB2u16> VABMap2u16,VABMap2us;
typedef VABFormatMap<VB2u32> VABMap2u32,VABMap2ui;
typedef VABFormatMap<VB2f> VABMap2f;
typedef VABFormatMap<VB2d> VABMap2d;
typedef VABFormatMap<VB3i32> VABMap3i32,VABMap3i;
typedef VABFormatMap<VB3u32> VABMap3u32,VABMap3ui;
typedef VABFormatMap<VB3f> VABMap3f;
typedef VABFormatMap<VB3d> VABMap3d;
typedef VABFormatMap<VB4i8> VABMap4i8 ,VABMap4b;
typedef VABFormatMap<VB4i16> VABMap4i16,VABMap4s;
typedef VABFormatMap<VB4i32> VABMap4i32,VABMap4i;
typedef VABFormatMap<VB4u8> VABMap4u8, VABMap4ub;
typedef VABFormatMap<VB4u16> VABMap4u16,VABMap4us;
typedef VABFormatMap<VB4u32> VABMap4u32,VABMap4ui;
typedef VABFormatMap<VB4f> VABMap4f;
typedef VABFormatMap<VB4d> VABMap4d;
VK_NAMESPACE_END

View File

@@ -44,6 +44,17 @@ namespace hgl
virtual ~VertexAttribDataAccess()=default;
void SetData(T *_data)
{
data =_data;
data_end=_data+count*C;
}
const bool IsValid()const
{
return data;
}
void Write(const T *ptr)
{
if(!ptr)return;

View File

@@ -57,4 +57,6 @@ public:
IndexBuffer *GetIBO(){return ibo;}
VAB *GetVAB(const uint index){return vab[index];}
};//class VertexDataManager
using VDM=VertexDataManager;
VK_NAMESPACE_END

View File

@@ -19,6 +19,8 @@ struct MaterialCreateConfig
AnsiString mtl_name; ///<材质名称
bool material_instance; ///<是否包含材质实例
RenderTargetOutputConfig rt_output; ///<渲染目标输出配置
uint32 shader_stage_flag_bit; ///<需要的shader
@@ -33,24 +35,29 @@ public:
mtl_name=name;
material_instance=false;
shader_stage_flag_bit=VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT;
prim=p;
}
int Comp(const MaterialCreateConfig &cfg)const
virtual int Comp(const MaterialCreateConfig &cfg)const
{
int off;
off=hgl_cmp(rt_output,cfg.rt_output);
off=material_instance-cfg.material_instance;
if(off)return(off);
off=hgl_cmp(rt_output,cfg.rt_output);
if(off)return(off);
off=(int)prim-(int)cfg.prim;
if(off)return(off);
return shader_stage_flag_bit-cfg.shader_stage_flag_bit;
off=shader_stage_flag_bit-cfg.shader_stage_flag_bit;
return off;
}
CompOperator(const MaterialCreateConfig &,Comp)

View File

@@ -8,7 +8,7 @@ namespace hgl
{
namespace SamplerName
{
constexpr const char Color[] = "TextureColor";
constexpr const char BaseColor[] = "TextureBaseColor";
}//namespace SamplerName
}//namespace mtl
}//namespace graph

View File

@@ -5,12 +5,14 @@
#define STD_MTL_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace mtl{
#define STD_MTL_NAMESPACE_END }}}
#define STD_MTL_NAMESPACE_USING using namespace hgl::graph::mtl;
#define STD_MTL_NAMESPACE hgl::graph::mtl
#define STD_MTL_NAMESPACE_USING using namespace STD_MTL_NAMESPACE;
#define STD_MTL_FUNC_NAMESPACE_BEGIN namespace hgl{namespace graph{namespace mtl{namespace func{
#define STD_MTL_FUNC_NAMESPACE_END }}}}
#define STD_MTL_FUNC NAMESPACE_USING using namespace hgl::graph::mtl::func;
#define STD_MTL_FUNC_NAMESPACE hgl::graph::mtl::func
#define STD_MTL_FUNC_NAMESPACE_USING using namespace STD_MTL_FUNC_NAMESPACE;
namespace hgl
{

View File

@@ -42,10 +42,24 @@ constexpr const ShaderBufferSource SBS_CameraInfo=
float znear,zfar;)"
};
constexpr const char LocalToWorldStruct[]="LocalToWorld";
constexpr const DescriptorSetType DST_LocalToWorld=DescriptorSetType::PerFrame;
constexpr const ShaderBufferSource SBS_LocalToWorld=
{
"LocalToWorldData",
"l2w",
R"(
mat4 mats[L2W_MAX_COUNT];
)"
};
// UBO必须严格指定数组的大小
// SSBO则不需要使用[]方式指定为动态大小数组
constexpr const char MaterialInstanceStruct[]="MaterialInstance";
constexpr const DescriptorSetType DST_MaterialInstance=DescriptorSetType::PerMaterial;
constexpr const ShaderBufferSource SBS_MaterialInstance=
{

View File

@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include<hgl/shadergen/MaterialDescriptorInfo.h>
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
@@ -33,7 +33,9 @@ namespace hgl{namespace graph
uint32_t mi_max_count;
UBODescriptor *mi_ubo;
uint32_t l2w_max_count;
uint32_t l2w_shader_stage;
UBODescriptor *l2w_ubo;
ShaderCreateInfoMap shader_map; ///<着色器列表

View File

@@ -21,8 +21,7 @@ namespace hgl
int hasInput(const char *);
void AddLocalToWorld();
void AddMaterialInstanceID();
void AddAssign();
void AddJoint();
};//class ShaderCreateInfoVertex:public ShaderCreateInfo

2
res

Submodule res updated: 5e5814c15e...475d8ad43c

View File

@@ -17,7 +17,6 @@ SET(SG_PRIMITIVE_SOURCE ${SG_INCLUDE_PATH}/VKPrimitive.h
Vulkan/VKPrimitive.cpp
Vulkan/VKPrimitiveData.cpp
Vulkan/VKPrimitiveData.h
${SG_INCLUDE_PATH}/VKRenderablePrimitiveCreater.h
${SG_INCLUDE_PATH}/PrimitiveCreater.h
PrimitiveCreater.cpp)
@@ -122,6 +121,7 @@ SET(VK_MEMORY_SOURCE ${SG_INCLUDE_PATH}/VKMemory.h
${SG_INCLUDE_PATH}/VKBuffer.h
${SG_INCLUDE_PATH}/VKIndexBuffer.h
${SG_INCLUDE_PATH}/VKArrayBuffer.h
${SG_INCLUDE_PATH}/VKBufferMap.h
Vulkan/VKMemory.cpp
Vulkan/VKMemoryAllocator.cpp
Vulkan/VKBuffer.cpp
@@ -237,6 +237,8 @@ SOURCE_GROUP("Vulkan\\Render Pass" FILES ${VK_RENDER_PASS_SOURCE})
SOURCE_GROUP("Vulkan\\Render Context" FILES ${VK_RENDER_CONTEXT_SOURCE})
SET(VK_CMD_BUFFER_SOURCE ${SG_INCLUDE_PATH}/VKCommandBuffer.h
${SG_INCLUDE_PATH}/VKIndirectCommandBuffer.h
Vulkan/VKIndirectCommandBuffer.cpp
Vulkan/VKCommandBuffer.cpp
Vulkan/VKCommandBufferRender.cpp)

View File

@@ -20,7 +20,7 @@ namespace hgl
if(!pc->Init("Rectangle",4,0))
return(nullptr);
VABMap2f vertex(pc,VAN::Position);
VABMap2f vertex(pc->GetVABMap(VAN::Position));
if(!vertex.IsValid())
return(nullptr);
@@ -48,7 +48,7 @@ namespace hgl
if(!pc->Init("RoundRectangle",4,0))
return(nullptr);
VABMap2f vertex(pc,VAN::Position);
VABMap2f vertex(pc->GetVABMap(VAN::Position));
vertex->WriteRectFan(rci->scope);
}
@@ -62,7 +62,7 @@ namespace hgl
if(!pc->Init("RoundRectangle",rci->round_per*4,8))
return(nullptr);
VABMap2f vertex(pc,VAN::Position);
VABMap2f vertex(pc->GetVABMap(VAN::Position));
Vector2f *coord=new Vector2f[rci->round_per];
@@ -133,8 +133,8 @@ namespace hgl
if(!pc->Init("Circle",vertex_count,0))return(nullptr);
VABMap2f vertex(pc,VAN::Position);
VABMap4f color(pc,VAN::Color);
VABMap2f vertex(pc->GetVABMap(VAN::Position));
VABMap4f color(pc->GetVABMap(VAN::Color));
if(!vertex.IsValid())
return(nullptr);
@@ -169,7 +169,10 @@ namespace hgl
if(!pc->Init("PlaneGrid",((pgci->grid_size.Width()+1)+(pgci->grid_size.Height()+1))*2,0))
return(nullptr);
VABMap3f vertex(pc,VAN::Position);
VABMap2f vertex(pc->GetVABMap(VAN::Position));
if(!vertex.IsValid())
return(nullptr);
const float right=float(pgci->grid_size.Width())/2.0f;
const float left =-right;
@@ -179,17 +182,17 @@ namespace hgl
for(uint row=0;row<=pgci->grid_size.Height();row++)
{
vertex->WriteLine( Vector3f(left ,top+row,0),
Vector3f(right,top+row,0));
vertex->WriteLine( Vector2f(left ,top+row),
Vector2f(right,top+row));
}
for(uint col=0;col<=pgci->grid_size.Width();col++)
{
vertex->WriteLine(Vector3f(left+col,top, 0),
Vector3f(left+col,bottom,0));
vertex->WriteLine(Vector2f(left+col,top ),
Vector2f(left+col,bottom));
}
VABMap1f lum(pc,VAN::Luminance);
VABMap1f lum(pc->GetVABMap(VAN::Luminance));
if(lum.IsValid())
{
@@ -229,21 +232,21 @@ namespace hgl
return(nullptr);
{
VABMap3f normal(pc,VAN::Normal);
VABMap3f normal(pc->GetVABMap(VAN::Normal));
if(normal.IsValid())
normal->RepeatWrite(xy_normal,4);
}
{
VABMap3f tangent(pc,VAN::Tangent);
VABMap3f tangent(pc->GetVABMap(VAN::Tangent));
if(tangent.IsValid())
tangent->RepeatWrite(xy_tangent,4);
}
{
VABMap2f tex_coord(pc,VAN::TexCoord);
VABMap2f tex_coord(pc->GetVABMap(VAN::TexCoord));
if(tex_coord.IsValid())
tex_coord->Write(xy_tex_coord,4);
@@ -329,7 +332,7 @@ namespace hgl
{
RANGE_CHECK_RETURN_NULLPTR(cci->color_type);
VABMap4f color(pc,VAN::Color);
VABMap4f color(pc->GetVABMap(VAN::Color));
if(color.IsValid())
{
@@ -357,7 +360,7 @@ namespace hgl
template<typename T>
void CreateSphereIndices(PrimitiveCreater *pc,uint numberParallels,const uint numberSlices)
{
IBMap<T> ib_map(pc);
IBTypeMap<T> ib_map(pc->GetIBMap());
T *tp=ib_map;
for (uint i = 0; i < numberParallels; i++)
@@ -470,10 +473,10 @@ namespace hgl
if(!pc->Init("Sphere",numberVertices,numberIndices))
return(nullptr);
VABRawMapFloat vertex (pc,VF_V3F,VAN::Position);
VABRawMapFloat normal (pc,VF_V3F,VAN::Normal);
VABRawMapFloat tangent (pc,VF_V3F,VAN::Tangent);
VABRawMapFloat tex_coord(pc,VF_V2F,VAN::TexCoord);
VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F);
VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F);
VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F);
VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F);
float *vp=vertex;
float *np=normal;
@@ -559,10 +562,10 @@ namespace hgl
if(!pc->Init("Dome",numberVertices,numberIndices))
return(nullptr);
VABRawMapFloat vertex (pc,VF_V3F,VAN::Position);
VABRawMapFloat normal (pc,VF_V3F,VAN::Normal);
VABRawMapFloat tangent (pc,VF_V3F,VAN::Tangent);
VABRawMapFloat tex_coord(pc,VF_V2F,VAN::TexCoord);
VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F);
VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F);
VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F);
VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F);
float *vp=vertex;
float *np=normal;
@@ -634,7 +637,7 @@ namespace hgl
template<typename T>
void CreateTorusIndices(PrimitiveCreater *pc,uint numberSlices,uint numberStacks)
{
IBMap<T> ib_map(pc);
IBTypeMap<T> ib_map(pc->GetIBMap());
T *tp=ib_map;
// loop counters
@@ -707,10 +710,10 @@ namespace hgl
if(!pc->Init("Torus",numberVertices,numberIndices))
return(nullptr);
VABRawMapFloat vertex (pc,VF_V3F,VAN::Position);
VABRawMapFloat normal (pc,VF_V3F,VAN::Normal);
VABRawMapFloat tangent (pc,VF_V3F,VAN::Tangent);
VABRawMapFloat tex_coord(pc,VF_V2F,VAN::TexCoord);
VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F);
VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F);
VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F);
VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F);
float *vp=vertex;
float *np=normal;
@@ -785,7 +788,7 @@ namespace hgl
template<typename T>
void CreateCylinderIndices(PrimitiveCreater *pc,const uint numberSlices)
{
IBMap<T> ib_map(pc);
IBTypeMap<T> ib_map(pc->GetIBMap());
T *tp=ib_map;
uint i;
@@ -849,10 +852,10 @@ namespace hgl
if (cci->numberSlices < 3 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES)
return nullptr;
VABRawMapFloat vertex (pc,VF_V3F,VAN::Position);
VABRawMapFloat normal (pc,VF_V3F,VAN::Normal);
VABRawMapFloat tangent (pc,VF_V3F,VAN::Tangent);
VABRawMapFloat tex_coord(pc,VF_V2F,VAN::TexCoord);
VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F);
VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F);
VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F);
VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F);
float *vp=vertex;
float *np=normal;
@@ -1022,7 +1025,7 @@ namespace hgl
template<typename T>
void CreateConeIndices(PrimitiveCreater *pc,const uint numberSlices,const uint numberStacks)
{
IBMap<T> ib_map(pc);
IBTypeMap<T> ib_map(pc->GetIBMap());
T *tp=ib_map;
// Bottom
@@ -1079,10 +1082,10 @@ namespace hgl
if (cci->numberSlices < 3 || cci->numberStacks < 1 || numberVertices > GLUS_MAX_VERTICES || numberIndices > GLUS_MAX_INDICES)
return nullptr;
VABRawMapFloat vertex (pc,VF_V3F,VAN::Position);
VABRawMapFloat normal (pc,VF_V3F,VAN::Normal);
VABRawMapFloat tangent (pc,VF_V3F,VAN::Tangent);
VABRawMapFloat tex_coord(pc,VF_V2F,VAN::TexCoord);
VABMapFloat vertex (pc->GetVABMap(VAN::Position),VF_V3F);
VABMapFloat normal (pc->GetVABMap(VAN::Normal),VF_V3F);
VABMapFloat tangent (pc->GetVABMap(VAN::Tangent),VF_V3F);
VABMapFloat tex_coord(pc->GetVABMap(VAN::TexCoord),VF_V2F);
float *vp=vertex;
float *np=normal;
@@ -1201,8 +1204,8 @@ namespace hgl
if(!pc->Init("Axis",6,0))
return(nullptr);
VABMap3f vertex(pc,VAN::Position);
VABMap4f color(pc,VAN::Color);
VABMap3f vertex(pc->GetVABMap(VAN::Position));
VABMap4f color(pc->GetVABMap(VAN::Color));
if(!vertex.IsValid()||!color.IsValid())
return(nullptr);
@@ -1253,7 +1256,7 @@ namespace hgl
{
RANGE_CHECK_RETURN_NULLPTR(cci->color_type);
VABMap4f color(pc,VAN::Color);
VABMap4f color(pc->GetVABMap(VAN::Color));
if(color.IsValid())
{

View File

@@ -6,6 +6,7 @@
#include<hgl/graph/VKRenderAssign.h>
#include<hgl/util/sort/Sort.h>
#include"RenderAssignBuffer.h"
#include<hgl/graph/VertexDataManager.h>
/**
*
@@ -15,12 +16,18 @@
* for(pipeline)
* for(material_instance)
* for(vab)
*
*
* 关于Indirect Command Buffer
建立一个大的IndirectCommandBuffer用于存放所有的渲染指令包括那些不能使用Indirect渲染的。
这样就可以保证所有的渲染操作就算要切VBO也不需要切换INDIRECT缓冲区定位指令也很方便。
*/
template<>
int Comparator<hgl::graph::RenderNode>::compare(const hgl::graph::RenderNode &obj_one,const hgl::graph::RenderNode &obj_two) const
{
int off;
hgl::int64 off;
hgl::graph::Renderable *ri_one=obj_one.ri;
hgl::graph::Renderable *ri_two=obj_two.ri;
@@ -34,15 +41,31 @@ int Comparator<hgl::graph::RenderNode>::compare(const hgl::graph::RenderNode &ob
return off;
}
//比较模型
auto *prim_one=ri_one->GetPrimitive();
auto *prim_two=ri_two->GetPrimitive();
//比如VDM
{
off=ri_one->GetPrimitive()
-ri_two->GetPrimitive();
off=prim_one->GetVDM()
-prim_two->GetVDM();
if(off)
return off;
}
//比较模型
{
off=prim_one
-prim_two;
if(off)
{
off=prim_one->GetVertexOffset()-prim_two->GetVertexOffset(); //保证vertex offset小的在前面
return off;
}
}
return 0;
}
@@ -53,24 +76,21 @@ MaterialRenderList::MaterialRenderList(GPUDevice *d,bool l2w,Material *m)
cmd_buf=nullptr;
material=m;
if(l2w)
l2w_buffer=new RenderL2WBuffer(device);
else
l2w_buffer=nullptr;
assign_buffer=new RenderAssignBuffer(device,material);
if(material->HasMI())
mi_buffer=new RenderMIBuffer(device,material->GetMIDataBytes());
else
mi_buffer=nullptr;
vab_list=new VABList(material->GetVertexInput()->GetCount());
vbo_list=new VBOList(material->GetVertexInput()->GetCount());
icb_draw=nullptr;
icb_draw_indexed=nullptr;
}
MaterialRenderList::~MaterialRenderList()
{
SAFE_CLEAR(vbo_list);
SAFE_CLEAR(mi_buffer);
SAFE_CLEAR(l2w_buffer);
SAFE_CLEAR(icb_draw_indexed)
SAFE_CLEAR(icb_draw)
SAFE_CLEAR(vab_list);
SAFE_CLEAR(assign_buffer);
}
void MaterialRenderList::Add(Renderable *ri,const Matrix4f &mat)
@@ -94,36 +114,52 @@ void MaterialRenderList::End()
Stat();
if(l2w_buffer)
{
l2w_buffer->WriteNode(rn_list.GetData(),node_count);
}
if(mi_buffer)
{
StatMI();
mi_buffer->WriteNode(rn_list.GetData(),node_count,mi_set);
}
if(assign_buffer)
assign_buffer->WriteNode(rn_list);
}
void MaterialRenderList::RenderItem::Set(Renderable *ri)
{
pipeline =ri->GetPipeline();
mi =ri->GetMaterialInstance();
vid =ri->GetVertexInputData();
pipeline=ri->GetPipeline();
mi =ri->GetMaterialInstance();
pdb =ri->GetDataBuffer();
prd =ri->GetRenderData();
}
void MaterialRenderList::StatMI()
void MaterialRenderList::ReallocICB()
{
mi_set.Clear();
const uint32_t icb_new_count=power_to_2(rn_list.GetCount());
for(RenderNode &rn:rn_list)
mi_set.Add(rn.ri->GetMaterialInstance());
if(mi_set.GetCount()>material->GetMIMaxCount())
if(icb_draw)
{
//超出最大数量了怎么办???
if(icb_new_count<=icb_draw->GetMaxCount())
return;
delete icb_draw;
icb_draw=nullptr;
delete icb_draw_indexed;
icb_draw_indexed=nullptr;
}
icb_draw=device->CreateIndirectDrawBuffer(icb_new_count);
icb_draw_indexed=device->CreateIndirectDrawIndexedBuffer(icb_new_count);
}
void MaterialRenderList::WriteICB(VkDrawIndirectCommand *dicp,RenderItem *ri)
{
dicp->vertexCount =ri->prd->vertex_count;
dicp->instanceCount =ri->instance_count;
dicp->firstVertex =ri->prd->vertex_offset;
dicp->firstInstance =ri->first_instance;
}
void MaterialRenderList::WriteICB(VkDrawIndexedIndirectCommand *diicp,RenderItem *ri)
{
diicp->indexCount =ri->prd->index_count;
diicp->instanceCount=ri->instance_count;
diicp->firstIndex =ri->prd->first_index;
diicp->vertexOffset =ri->prd->vertex_offset;
diicp->firstInstance=ri->first_instance;
}
void MaterialRenderList::Stat()
@@ -131,6 +167,11 @@ void MaterialRenderList::Stat()
const uint count=rn_list.GetCount();
RenderNode *rn=rn_list.GetData();
ReallocICB();
VkDrawIndirectCommand *dicp=icb_draw->MapCmd();
VkDrawIndexedIndirectCommand *diicp=icb_draw_indexed->MapCmd();
ri_array.Clear();
ri_array.Alloc(count);
@@ -138,67 +179,88 @@ void MaterialRenderList::Stat()
ri_count=1;
ri->first=0;
ri->count=1;
ri->first_instance=0;
ri->instance_count=1;
ri->Set(rn->ri);
last_pipeline =ri->pipeline;
last_vid =ri->vid;
last_data_buffer=ri->pdb;
last_vdm =ri->pdb->vdm;
last_render_data=ri->prd;
++rn;
for(uint i=1;i<count;i++)
{
if(last_pipeline==rn->ri->GetPipeline())
if(last_vid->Comp(rn->ri->GetVertexInputData()))
{
++ri->count;
++rn;
continue;
}
if(last_data_buffer->Comp(rn->ri->GetDataBuffer()))
if(last_render_data->_Comp(rn->ri->GetRenderData())==0)
{
++ri->instance_count;
++rn;
continue;
}
if(ri->pdb->vdm)
{
if(ri->pdb->ibo)
WriteICB(diicp,ri);
else
WriteICB(dicp,ri);
++dicp;
++diicp;
}
++ri_count;
++ri;
ri->first=i;
ri->count=1;
ri->first_instance=i;
ri->instance_count=1;
ri->Set(rn->ri);
last_pipeline =ri->pipeline;
last_vid =ri->vid;
last_data_buffer=ri->pdb;
last_vdm =ri->pdb->vdm;
last_render_data=ri->prd;
++rn;
}
if(ri->pdb->vdm)
{
if(ri->pdb->ibo)
WriteICB(diicp,ri);
else
WriteICB(dicp,ri);
}
icb_draw->Unmap();
icb_draw_indexed->Unmap();
}
bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
bool MaterialRenderList::BindVAB(const PrimitiveDataBuffer *pdb,const uint ri_index)
{
//binding号都是在VertexInput::CreateVIL时连续紧密排列生成的所以bind时first_binding写0就行了。
//const VIL *vil=last_vil;
//if(vil->GetCount(VertexInputGroup::Basic)!=vid->binding_count)
//if(vil->GetCount(VertexInputGroup::Basic)!=prb->vab_count)
// return(false); //这里基本不太可能因为CreateRenderable时就会检查值是否一样
vbo_list->Restart();
vab_list->Restart();
//Basic组它所有的VAB信息均来自于Primitive由vid参数传递进来
{
vbo_list->Add(vid->buffer_list,vid->buffer_offset,vid->binding_count);
vab_list->Add(pdb->vab_list,
pdb->vab_offset,
pdb->vab_count);
}
if(l2w_buffer)//LocalToWorld组由RenderList合成
{
for(uint i=0;i<4;i++)
l2w_buffer_size[i]=ri_index*16; //mat4每列都是rgba32f自然是16字节
if(assign_buffer) //L2W/MI分发组
vab_list->Add(assign_buffer->GetVAB(),0);//ASSIGN_VAB_STRIDE_BYTES*ri_index);
vbo_list->Add(l2w_buffer->GetVBO(),l2w_buffer_size,4);
}
if(mi_buffer) //材质实例组
vbo_list->Add(mi_buffer->GetVBO(),MI_VAB_STRIDE_BYTES*ri_index);
//if(!vbo_list.IsFull()) //Joint组暂未支持
//if(!vab_list.IsFull()) //Joint组暂未支持
//{
// const uint joint_id_binding_count=vil->GetCount(VertexInputGroup::JointID);
@@ -206,7 +268,7 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
// {
// count+=joint_id_binding_count;
// if(count<binding_count) //JointWeight组
// if(count<vab_count) //JointWeight组
// {
// const uint joing_weight_binding_count=vil->GetCount(VertexInputGroup::JointWeight);
@@ -226,18 +288,29 @@ bool MaterialRenderList::Bind(const VertexInputData *vid,const uint ri_index)
// }
//}
//if(count!=binding_count)
//if(count!=vab_count)
//{
// //还有没支持的绑定组????
// return(false);
//}
cmd_buf->BindVBO(vbo_list);
cmd_buf->BindVAB(vab_list);
return(true);
}
void MaterialRenderList::ProcIndirectRender()
{
if(last_data_buffer->ibo)
icb_draw_indexed->DrawIndexed(*cmd_buf,first_indirect_draw_index,indirect_draw_count);
else
icb_draw->Draw(*cmd_buf,first_indirect_draw_index,indirect_draw_count);
first_indirect_draw_index=-1;
indirect_draw_count=0;
}
void MaterialRenderList::Render(RenderItem *ri)
{
if(last_pipeline!=ri->pipeline)
@@ -245,24 +318,35 @@ void MaterialRenderList::Render(RenderItem *ri)
cmd_buf->BindPipeline(ri->pipeline);
last_pipeline=ri->pipeline;
last_vid=nullptr;
last_data_buffer=nullptr;
//这里未来尝试换pipeline同时不换mi/primitive是否需要重新绑定mi/primitive
}
if(!ri->vid->Comp(last_vid))
if(!ri->pdb->Comp(last_data_buffer)) //换buf了
{
Bind(ri->vid,ri->first);
last_vid=ri->vid;
if(indirect_draw_count) //如果有间接绘制的数据,赶紧给画了
ProcIndirectRender();
last_data_buffer=ri->pdb;
last_render_data=nullptr;
BindVAB(ri->pdb,ri->first_instance);
if(ri->pdb->ibo)
cmd_buf->BindIBO(ri->pdb->ibo);
}
if(last_vid->ib_access)
if(ri->pdb->vdm)
{
cmd_buf->DrawIndexed(last_vid->ib_access,ri->count);
if(indirect_draw_count==0)
first_indirect_draw_index=ri->first_instance;
++indirect_draw_count;
}
else
{
cmd_buf->Draw(last_vid->vertex_count,ri->count);
cmd_buf->Draw(ri->pdb,ri->prd,ri->instance_count,ri->first_instance);
}
}
@@ -277,20 +361,24 @@ void MaterialRenderList::Render(RenderCmdBuffer *rcb)
cmd_buf=rcb;
RenderItem *ri=ri_array.GetData();
last_pipeline =nullptr;
last_vid =nullptr;
last_data_buffer=nullptr;
last_vdm =nullptr;
last_render_data=nullptr;
if(mi_buffer)
mi_buffer->Bind(material);
if(assign_buffer)
assign_buffer->Bind(material);
cmd_buf->BindDescriptorSets(material);
RenderItem *ri=ri_array.GetData();
for(uint i=0;i<ri_count;i++)
{
Render(ri);
++ri;
}
if(indirect_draw_count) //如果有间接绘制的数据,赶紧给画了
ProcIndirectRender();
}
VK_NAMESPACE_END

View File

@@ -39,10 +39,10 @@ void PrimitiveCreater::Clear()
index_number =0;
index_type =IndexType::ERR;
iba =nullptr;
ibo =nullptr;
}
bool PrimitiveCreater::Init(const AnsiString &pname,const VkDeviceSize vertex_count,const VkDeviceSize index_count,IndexType it)
bool PrimitiveCreater::Init(const AnsiString &pname,const uint32_t vertex_count,const uint32_t index_count,IndexType it)
{
if(prim_data) //已经初始化过了
return(false);
@@ -84,9 +84,9 @@ bool PrimitiveCreater::Init(const AnsiString &pname,const VkDeviceSize vertex_co
if(index_number>0)
{
iba=prim_data->InitIBO(index_number,index_type);
ibo=prim_data->InitIBO(index_number,index_type);
if(!iba)
if(!ibo)
{
delete prim_data;
return(false);
@@ -99,8 +99,8 @@ bool PrimitiveCreater::Init(const AnsiString &pname,const VkDeviceSize vertex_co
if(du)
{
du->SetBuffer( iba->buffer->GetBuffer(), prim_name+":IndexBuffer:Buffer");
du->SetDeviceMemory(iba->buffer->GetVkMemory(), prim_name+":IndexBuffer:Memory");
du->SetBuffer( ibo->GetBuffer(), prim_name+":IndexBuffer:Buffer");
du->SetDeviceMemory(ibo->GetVkMemory(), prim_name+":IndexBuffer:Memory");
}
}
#endif//_DEBUG
@@ -111,58 +111,85 @@ bool PrimitiveCreater::Init(const AnsiString &pname,const VkDeviceSize vertex_co
return(true);
}
VABAccess *PrimitiveCreater::AcquireVAB(const AnsiString &name,const VkFormat &acquire_format,const void *data)
const int PrimitiveCreater::InitVAB(const AnsiString &name,const VkFormat format,const void *data)
{
if(!prim_data)return(nullptr);
if(name.IsEmpty())return(nullptr);
if(!prim_data)return(-1);
VABAccess *vab_access=prim_data->InitVAB(name,acquire_format,data);
const int vab_index=prim_data->GetVABIndex(name);
if(!vab_access)
return(nullptr);
if(vab_index<0||vab_index>=vil->GetVertexAttribCount())
return(-1);
if(format!=VK_FORMAT_UNDEFINED)
{
const VIF *vif=vil->GetConfig(vab_index);
if(vif->format!=format)
return(-2);
}
VAB *vab=prim_data->GetVAB(vab_index);
if(!vab)
{
vab=prim_data->InitVAB(vab_index,data);
if(!vab)
return(-1);
#ifdef _DEBUG
if(!vdm&&vab_access->vab)
{
DebugUtils *du=device->GetDebugUtils();
if(du)
if (!vdm)
{
du->SetBuffer( vab_access->vab->GetBuffer(), prim_name+":VAB:Buffer:"+name);
du->SetDeviceMemory(vab_access->vab->GetVkMemory(), prim_name+":VAB:Memory:"+name);
DebugUtils *du=device->GetDebugUtils();
if (du)
{
du->SetBuffer(vab->GetBuffer(), prim_name+":VAB:Buffer:"+name);
du->SetDeviceMemory(vab->GetVkMemory(), prim_name+":VAB:Memory:"+name);
}
}
}
#endif//_DEBUG
}
return vab_access;
return(vab_index);
}
void *PrimitiveCreater::MapIBO()
VABMap *PrimitiveCreater::GetVABMap(const AnsiString &name,const VkFormat format)
{
if(!prim_data)return(nullptr);
if(!iba)return(nullptr);
const int vab_index=InitVAB(name,format,nullptr);
return iba->buffer->Map(iba->start,iba->count);
if(vab_index<0)return nullptr;
return prim_data->GetVABMap(vab_index);
}
void PrimitiveCreater::UnmapIBO()
bool PrimitiveCreater::WriteVAB(const AnsiString &name,const VkFormat format,const void *data)
{
if(iba)
iba->buffer->Unmap();
if(!prim_data)return(false);
if(!data)return(false);
return InitVAB(name,format,data)>=0;
}
bool PrimitiveCreater::WriteIBO(const void *data,const VkDeviceSize count)
IBMap *PrimitiveCreater::GetIBMap()
{
if(!prim_data)
return(nullptr);
return prim_data->GetIBMap();
}
bool PrimitiveCreater::WriteIBO(const void *data,const uint32_t count)
{
if(!data)return(false);
if(!prim_data)return(false);
IBAccess *iba=prim_data->GetIBAccess();
IndexBuffer *ibo=prim_data->GetIBO();
if(count>0&&count>index_number)
return(false);
return iba->buffer->Write(data,iba->start,count);
return ibo->Write(data,prim_data->GetFirstIndex(),count);
}
Primitive *PrimitiveCreater::Create()
@@ -170,6 +197,8 @@ Primitive *PrimitiveCreater::Create()
if(!prim_data)
return(nullptr);
prim_data->UnmapAll();
Primitive *primitive=new Primitive(prim_name,prim_data);
if(!primitive)

View File

@@ -8,184 +8,186 @@
#include<hgl/graph/mtl/UBOCommon.h>
VK_NAMESPACE_BEGIN
RenderL2WBuffer::RenderL2WBuffer(GPUDevice *dev)
{
hgl_zero(*this);
device=dev;
}
void RenderL2WBuffer::Clear()
{
SAFE_CLEAR(l2w_vbo[0])
SAFE_CLEAR(l2w_vbo[1])
SAFE_CLEAR(l2w_vbo[2])
SAFE_CLEAR(l2w_vbo[3])
node_count=0;
}
#ifdef _DEBUG
namespace
{
constexpr const char *l2w_buffer_name[]=
{
"VAB:Buffer:LocalToWorld:0",
"VAB:Buffer:LocalToWorld:1",
"VAB:Buffer:LocalToWorld:2",
"VAB:Buffer:LocalToWorld:3"
};
constexpr const char *l2w_memory_name[]=
{
"VAB:Memory:LocalToWorld:0",
"VAB:Memory:LocalToWorld:1",
"VAB:Memory:LocalToWorld:2",
"VAB:Memory:LocalToWorld:3"
};
}
#endif//_DEBUG
void RenderL2WBuffer::Alloc(const uint nc)
{
Clear();
{
node_count=nc;
for(uint i=0;i<4;i++)
{
l2w_vbo[i]=device->CreateVAB(VF_V4F,node_count);
l2w_buffer[i]=l2w_vbo[i]->GetBuffer();
}
}
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
{
for(int i=0;i<4;i++)
{
du->SetBuffer(l2w_buffer[i],l2w_buffer_name[i]);
du->SetDeviceMemory(l2w_vbo[i]->GetVkMemory(),l2w_memory_name[i]);
}
}
#endif//_DEBUG
}
void RenderL2WBuffer::WriteNode(RenderNode *render_node,const uint count)
{
RenderNode *rn;
Alloc(count);
glm::vec4 *tp;
for(uint col=0;col<4;col++)
{
tp=(glm::vec4 *)(l2w_vbo[col]->DeviceBuffer::Map());
rn=render_node;
for(uint i=0;i<count;i++)
{
*tp=rn->local_to_world[col];
++tp;
++rn;
}
l2w_vbo[col]->Unmap();
}
}
VK_NAMESPACE_END
VK_NAMESPACE_BEGIN
RenderMIBuffer::RenderMIBuffer(GPUDevice *dev,const uint mi_bytes)
RenderAssignBuffer::RenderAssignBuffer(GPUDevice *dev,Material *mtl)
{
hgl_zero(*this);
device=dev;
mi_data_bytes=mi_bytes;
material=mtl;
mi_data_bytes=mtl->GetMIDataBytes();
LW2_MAX_COUNT=dev->GetUBORange()/sizeof(Matrix4f);
l2w_buffer_max_count=0;
l2w_buffer=nullptr;
mi_buffer=nullptr;
}
void RenderMIBuffer::Bind(Material *mtl)const
void RenderAssignBuffer::Bind(Material *mtl)const
{
if(!mtl)return;
mtl->BindUBO(DescriptorSetType::PerMaterial,mtl::SBS_MaterialInstance.name,mi_data_buffer);
mtl->BindUBO(mtl::DST_LocalToWorld, mtl::SBS_LocalToWorld.name, l2w_buffer);
mtl->BindUBO(mtl::DST_MaterialInstance, mtl::SBS_MaterialInstance.name, mi_buffer);
}
void RenderMIBuffer::Clear()
void RenderAssignBuffer::Clear()
{
SAFE_CLEAR(mi_data_buffer);
SAFE_CLEAR(mi_vab);
mi_count=0;
node_count=0;
SAFE_CLEAR(l2w_buffer);
SAFE_CLEAR(mi_buffer);
SAFE_CLEAR(assign_vab);
}
void RenderMIBuffer::Alloc(const uint nc,const uint mc)
void RenderAssignBuffer::StatL2W(const RenderNodeList &rn_list)
{
Clear();
node_count=nc;
if(mi_data_bytes>0&&mc>0)
if(!l2w_buffer)
{
mi_count=mc;
mi_data_buffer=device->CreateUBO(mi_data_bytes*mi_count);
l2w_buffer_max_count=power_to_2(rn_list.GetCount());
}
else if(rn_list.GetCount()>l2w_buffer_max_count)
{
l2w_buffer_max_count=power_to_2(rn_list.GetCount());
SAFE_CLEAR(l2w_buffer);
}
mi_vab=device->CreateVAB(MI_VAB_FMT,node_count);
mi_buffer=mi_vab->GetBuffer();
if(!l2w_buffer)
{
l2w_buffer=device->CreateUBO(sizeof(Matrix4f)*l2w_buffer_max_count);
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
{
du->SetBuffer(mi_data_buffer->GetBuffer(),"UBO:Buffer:MaterialInstance");
du->SetDeviceMemory(mi_data_buffer->GetVkMemory(),"UBO:Memory:MaterialInstance");
du->SetBuffer(mi_vab->GetBuffer(),"VAB:Buffer:MaterialInstanceID");
du->SetDeviceMemory(mi_vab->GetVkMemory(),"VAB:Memory:MaterialInstanceID");
du->SetBuffer(l2w_buffer->GetBuffer(),"UBO:Buffer:LocalToWorld");
du->SetDeviceMemory(l2w_buffer->GetVkMemory(),"UBO:Memory:LocalToWorld");
}
#endif//_DEBUG
}
void RenderMIBuffer::WriteNode(RenderNode *render_node,const uint count,const MaterialInstanceSets &mi_set)
{
RenderNode *rn;
Alloc(count,mi_set.GetCount());
uint8 *mip=(uint8 *)(mi_data_buffer->Map());
for(MaterialInstance *mi:mi_set)
{
memcpy(mip,mi->GetMIData(),mi_data_bytes);
mip+=mi_data_bytes;
}
mi_data_buffer->Unmap();
RenderNode *rn=rn_list.GetData();
Matrix4f *l2wp=(Matrix4f *)(l2w_buffer->DeviceBuffer::Map());
uint16 *idp=(uint16 *)(mi_vab->DeviceBuffer::Map());
for(uint i=0;i<rn_list.GetCount();i++)
{
*l2wp=rn->local_to_world;
++l2wp;
++rn;
}
l2w_buffer->Unmap();
}
void RenderAssignBuffer::StatMI(const RenderNodeList &rn_list)
{
mi_set.Clear();
if(mi_data_bytes<=0) //没有材质实例数据
return;
if(!mi_buffer)
{
mi_set.PreAlloc(power_to_2(rn_list.GetCount()));
}
else if(rn_list.GetCount()>mi_set.GetAllocCount())
{
mi_set.PreAlloc(power_to_2(rn_list.GetCount()));
SAFE_CLEAR(mi_buffer);
}
if(!mi_buffer)
{
mi_buffer=device->CreateUBO(mi_data_bytes*mi_set.GetAllocCount());
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
{
du->SetBuffer(mi_buffer->GetBuffer(),"UBO:Buffer:MaterialInstanceData");
du->SetDeviceMemory(mi_buffer->GetVkMemory(),"UBO:Memory:MaterialInstanceData");
}
#endif//_DEBUG
}
mi_set.PreAlloc(rn_list.GetCount());
for(RenderNode &rn:rn_list)
mi_set.Add(rn.ri->GetMaterialInstance());
if(mi_set.GetCount()>material->GetMIMaxCount())
{
//超出最大数量了怎么办???
}
//合并材质实例数据
{
uint8 *mip=(uint8 *)(mi_buffer->Map());
for(MaterialInstance *mi:mi_set)
{
memcpy(mip,mi->GetMIData(),mi_data_bytes);
mip+=mi_data_bytes;
}
mi_buffer->Unmap();
}
}
void RenderAssignBuffer::WriteNode(const RenderNodeList &rn_list)
{
if(rn_list.GetCount()<=0)
return;
StatL2W(rn_list);
StatMI(rn_list);
{
rn=render_node;
for(uint i=0;i<count;i++)
if(!assign_vab)
{
*idp=mi_set.Find(rn->ri->GetMaterialInstance());
++idp;
node_count=power_to_2(rn_list.GetCount());
}
else if(node_count<rn_list.GetCount())
{
node_count=power_to_2(rn_list.GetCount());
SAFE_CLEAR(assign_vab);
}
if(!assign_vab)
{
assign_vab=device->CreateVAB(ASSIGN_VAB_FMT,node_count);
assign_buffer=assign_vab->GetBuffer();
#ifdef _DEBUG
DebugUtils *du=device->GetDebugUtils();
if(du)
{
du->SetBuffer(assign_vab->GetBuffer(),"VAB:Buffer:AssignData");
du->SetDeviceMemory(assign_vab->GetVkMemory(),"VAB:Memory:AssignData");
}
#endif//_DEBUG
}
}
//生成材质实例ID列表
{
RenderNode *rn=rn_list.GetData();
AssignData *adp=(AssignData *)(assign_vab->DeviceBuffer::Map());
for(uint i=0;i<rn_list.GetCount();i++)
{
adp->l2w=i;
adp->mi=mi_set.Find(rn->ri->GetMaterialInstance());
++adp;
++rn;
}
}
mi_vab->Unmap();
assign_vab->Unmap();
}
}
VK_NAMESPACE_END

View File

@@ -16,6 +16,7 @@ VK_NAMESPACE_BEGIN
// 如果一定要使用超过16K/64K硬件限制的容量有两种办法
// 一、分多次渲染使用UBO Offset偏移UBO数据区。
// 二、使用SSBO但这样会导致性能下降所以不推荐使用。
// 三、使用纹理保存材质实例数据,但这样会导致性能下降,所以不推荐使用。
// 但我们不解决这个问题
// 我们天然要求将材质实例数据分为两个等级同时要求一次渲染不能超过256种材质实例。
@@ -25,73 +26,71 @@ VK_NAMESPACE_BEGIN
struct RenderNode;
class MaterialInstance;
class RenderL2WBuffer
{
GPUDevice *device;
uint node_count; ///<渲染节点数量
VAB *l2w_vbo[4];
VkBuffer l2w_buffer[4];
private:
void Alloc(const uint nc);
void Clear();
public:
const VkBuffer *GetVBO()const{return l2w_buffer;}
public:
RenderL2WBuffer(GPUDevice *dev);
~RenderL2WBuffer(){Clear();}
void WriteNode(RenderNode *render_node,const uint count);
};//class RenderL2WBuffer
/*
* 渲染节点额外提供的数据
*/
class RenderMIBuffer
class RenderAssignBuffer
{
struct AssignData
{
uint16 l2w;
uint16 mi;
};
uint LW2_MAX_COUNT;
private:
GPUDevice *device;
uint node_count; ///<渲染节点数量
Material *material;
uint32_t mi_data_bytes; ///<材质实例数据字节数
uint32_t mi_count; ///<材质实例数量
DeviceBuffer *mi_data_buffer; ///<材质实例数据(UBO/SSBO)
private: //LocalToWorld矩阵数据
VAB *mi_vab; ///<材质实例ID(R16UI格式)
VkBuffer mi_buffer;
uint32 l2w_buffer_max_count; ///<LocalToWorld矩阵最大数量
DeviceBuffer *l2w_buffer; ///<LocalToWorld矩阵数据(UBO/SSBO)
void StatL2W(const RenderNodeList &);
private: //材质实例数据
MaterialInstanceSets mi_set;
uint32_t mi_data_bytes; ///<单个材质实例数据字节数
DeviceBuffer *mi_buffer; ///<材质实例数据(UBO/SSBO)
void StatMI(const RenderNodeList &);
private: //分发数据
uint32 node_count; ///<节点数量
VAB *assign_vab; ///<分发数据VAB(RG16UI格式R存L2W IDG存材质实例ID)
VkBuffer assign_buffer; ///<分发数据Buffer
private:
void Alloc(const uint nc,const uint mc);
void Clear();
public:
const VkBuffer GetVBO()const{return mi_buffer;}
const VkBuffer GetVAB()const{return assign_buffer;}
void Bind(Material *)const;
public:
RenderMIBuffer(GPUDevice *dev,const uint32_t mi_bytes);
~RenderMIBuffer(){Clear();}
RenderAssignBuffer(GPUDevice *dev,Material *);
~RenderAssignBuffer(){Clear();}
//下一代将MaterialInstanceSets使用提前化这样不用每一次绘制都重新写入MI DATA可以提升效率。
//虽然这样就不自动化了,但我们要的就是不自动化。
//必须在外部全部准备好MaterialInstanceSets然后一次性写入。
//渲染时找不到就直接用0号材质实例
void WriteNode(RenderNode *render_node,const uint nc,const MaterialInstanceSets &mi_set);
};//struct RenderMIBuffer
//同样的LocalToWorld矩阵也可以提前化处理这样对于静态物体就只需要写入一次LocalToWorld矩阵了。
void WriteNode(const RenderNodeList &);
};//struct RenderAssignBuffer
VK_NAMESPACE_END

View File

@@ -13,7 +13,7 @@ namespace hgl
device=dev;
vil=_vil;
vi_count=_vil->GetCount();
vi_count=_vil->GetVertexAttribCount();
vif_list=_vil->GetVIFList(); //来自于Material不会被释放所以指针有效
vab_max_size=0;

View File

@@ -130,33 +130,32 @@ bool RenderCmdBuffer::BindDescriptorSets(Material *mtl)
return(true);
}
//void RenderCmdBuffer::BindIBO(const IBAccess *iba)
//{
// vkCmdBindIndexBuffer( cmd_buf,
// iba->buffer->GetBuffer(),
// iba->start,
// VkIndexType(iba->buffer->GetType()));
//}
bool RenderCmdBuffer::BindVBO(Renderable *ri)
void RenderCmdBuffer::BindIBO(IndexBuffer *ibo,const VkDeviceSize byte_offset)
{
if(!ri)
if(!ibo)return;
vkCmdBindIndexBuffer(cmd_buf,
ibo->GetBuffer(),
byte_offset,
VkIndexType(ibo->GetType()));
}
bool RenderCmdBuffer::BindDataBuffer(const PrimitiveDataBuffer *pdb)
{
if(!pdb)
return(false);
const VertexInputData *vid=ri->GetVertexInputData();
if(vid->binding_count<=0)
if(pdb->vab_count<=0)
return(false);
vkCmdBindVertexBuffers(cmd_buf,0,vid->binding_count,vid->buffer_list,vid->buffer_offset);
vkCmdBindVertexBuffers(cmd_buf,
0, //first binding
pdb->vab_count,
pdb->vab_list,
pdb->vab_offset); //vab byte offsets
IndexBuffer *indices_buffer=vid->ib_access->buffer;
if(indices_buffer)
vkCmdBindIndexBuffer(cmd_buf,
indices_buffer->GetBuffer(),
vid->ib_access->start,
VkIndexType(indices_buffer->GetType()));
if(pdb->ibo)
BindIBO(pdb->ibo);
return(true);
}
@@ -185,23 +184,40 @@ void RenderCmdBuffer::DrawIndexedIndirect( VkBuffer buffer,
vkCmdDrawIndexedIndirect(cmd_buf,buffer,offset+i*stride,1,stride);
}
void RenderCmdBuffer::Draw(const VertexInputData *vid)
void RenderCmdBuffer::Draw(const PrimitiveDataBuffer *pdb,const PrimitiveRenderData *prd,const uint32_t instance_count,const uint32_t first_instance)
{
if (vid->ib_access->buffer)
DrawIndexed(vid->ib_access->count);
if(!pdb||!prd)
return;
if (pdb->ibo)
vkCmdDrawIndexed( cmd_buf,
prd->index_count,
instance_count,
prd->first_index,
prd->vertex_offset, //这里的vertexOffset是针对所有VAB的
first_instance); //这里的first_instance针对的是instance Rate更新的VAB的起始实例数不是指instance批量渲染
else
Draw(vid->vertex_count);
vkCmdDraw( cmd_buf,
prd->vertex_count,
instance_count,
prd->vertex_offset,
first_instance);
}
void RenderCmdBuffer::DrawIndexed(const IBAccess *iba,const uint32_t instance_count)
{
if(!iba||instance_count<=0)return;
vkCmdBindIndexBuffer(cmd_buf,
iba->buffer->GetBuffer(),
iba->start*iba->buffer->GetStride(),
VkIndexType(iba->buffer->GetType()));
vkCmdDrawIndexed(cmd_buf,iba->count,instance_count,0,0,0);
}
//void RenderCmdBuffer::DrawIndexed(const IBAccess *iba,const uint32_t instance_count)
//{
// if(!iba||instance_count<=0)return;
//
// vkCmdBindIndexBuffer(cmd_buf,
// iba->buffer->GetBuffer(),
// iba->start*iba->buffer->GetStride(),
// VkIndexType(iba->buffer->GetType()));
//
// vkCmdDrawIndexed(cmd_buf,
// iba->count,
// instance_count,
// 0, //first index
// 0, //vertex offset
// 0); //first instance
//}
VK_NAMESPACE_END

View File

@@ -69,7 +69,7 @@ namespace
void DescriptorSet::Clear()
{
buffer_list.Clear();
vab_list.Clear();
image_list.Clear();
wds_list.Clear();
binded_sets.Clear();
@@ -101,7 +101,7 @@ bool DescriptorSet::BindUBO(const int binding,const DeviceBuffer *buf,const VkDe
DescriptorBufferInfo *buf_info=new DescriptorBufferInfo(buf,offset,range);
buffer_list.Add(buf_info);
vab_list.Add(buf_info);
const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
@@ -137,7 +137,7 @@ bool DescriptorSet::BindSSBO(const int binding,const DeviceBuffer *buf,const VkD
DescriptorBufferInfo *buf_info=new DescriptorBufferInfo(buf,offset,range);
buffer_list.Add(buf_info);
vab_list.Add(buf_info);
const VkDescriptorType desc_type=dynamic?VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;

View File

@@ -18,9 +18,9 @@ namespace
{
RANGE_CHECK_RETURN_NULLPTR(type);
const uint32_t binding_count=pld->binding_count[size_t(type)];
const uint32_t vab_count=pld->vab_count[size_t(type)];
if(!binding_count)
if(!vab_count)
return(nullptr);
DescriptorSetAllocateInfo alloc_info;
@@ -34,7 +34,7 @@ namespace
if(vkAllocateDescriptorSets(device,&alloc_info,&desc_set)!=VK_SUCCESS)
return(nullptr);
return(new DescriptorSet(device,binding_count,pld->pipeline_layout,desc_set));
return(new DescriptorSet(device,vab_count,pld->pipeline_layout,desc_set));
}
}//namespace

View File

@@ -0,0 +1,45 @@
#include<hgl/graph/VKIndirectCommandBuffer.h>
#include<hgl/graph/VKDevice.h>
VK_NAMESPACE_BEGIN
bool GPUDevice::CreateIndirectCommandBuffer(DeviceBufferData *buf,const uint32_t cmd_count,const uint32_t cmd_size,SharingMode sharing_mode)
{
const uint32_t size=cmd_count*cmd_size;
if(size<=0)return(false);
return CreateBuffer(buf,VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT,size,size,nullptr,sharing_mode);
}
IndirectDrawBuffer *GPUDevice::CreateIndirectDrawBuffer(const uint32_t cmd_count,SharingMode sm)
{
DeviceBufferData buf;
if(!CreateIndirectCommandBuffer(&buf,cmd_count,sizeof(VkDrawIndirectCommand),sm))
return(nullptr);
return(new IndirectDrawBuffer(attr->device,buf,cmd_count));
}
IndirectDrawIndexedBuffer *GPUDevice::CreateIndirectDrawIndexedBuffer(const uint32_t cmd_count,SharingMode sm)
{
DeviceBufferData buf;
if(!CreateIndirectCommandBuffer(&buf,cmd_count,sizeof(VkDrawIndexedIndirectCommand),sm))
return(nullptr);
return(new IndirectDrawIndexedBuffer(attr->device,buf,cmd_count));
}
IndirectDispatchBuffer *GPUDevice::CreateIndirectDispatchBuffer(const uint32_t cmd_count,SharingMode sm)
{
DeviceBufferData buf;
if(!CreateIndirectCommandBuffer(&buf,cmd_count,sizeof(VkDispatchIndirectCommand),sm))
return(nullptr);
return(new IndirectDispatchBuffer(attr->device,buf,cmd_count));
}
VK_NAMESPACE_END

View File

@@ -26,7 +26,7 @@ PipelineLayoutData *GPUDevice::CreatePipelineLayoutData(const MaterialDescriptor
return(nullptr);
}
pld->binding_count[i]=dslci->bindingCount;
pld->vab_count[i]=dslci->bindingCount;
pld->fin_dsl[pld->fin_dsl_count]=pld->layouts[i];
++pld->fin_dsl_count;

View File

@@ -9,7 +9,7 @@ struct PipelineLayoutData
{
VkDevice device;
int binding_count[DESCRIPTOR_SET_TYPE_COUNT];
int vab_count[DESCRIPTOR_SET_TYPE_COUNT];
VkDescriptorSetLayout layouts[DESCRIPTOR_SET_TYPE_COUNT];
VkDescriptorSetLayout fin_dsl[DESCRIPTOR_SET_TYPE_COUNT];

View File

@@ -51,14 +51,48 @@ const int Primitive::GetVABCount()const
return prim_data->GetVABCount();
}
VABAccess *Primitive::GetVABAccess(const AnsiString &name)
const int Primitive::GetVABIndex(const AnsiString &name)const
{
return prim_data->GetVABAccess(name);
return prim_data->GetVABIndex(name);
}
IBAccess *Primitive::GetIBAccess()
VAB *Primitive::GetVAB(const int vab_index)
{
return prim_data->GetIBAccess();
return prim_data->GetVAB(vab_index);
}
const int32_t Primitive::GetVertexOffset()const
{
return prim_data->GetVertexOffset();
}
VABMap *Primitive::GetVABMap(const int vab_index)
{
return prim_data->GetVABMap(vab_index);
}
const uint32_t Primitive::GetIndexCount()const
{
return prim_data->GetIndexCount();
}
IndexBuffer *Primitive::GetIBO()
{
return prim_data->GetIBO();
}
const uint32_t Primitive::GetFirstIndex()const
{
return prim_data->GetFirstIndex();
}
IBMap *Primitive::GetIBMap()
{
return prim_data->GetIBMap();
}
VertexDataManager *Primitive::GetVDM()
{
return prim_data->GetVDM();
}
VK_NAMESPACE_END

View File

@@ -7,25 +7,27 @@
VK_NAMESPACE_BEGIN
PrimitiveData::PrimitiveData(const VIL *_vil,const VkDeviceSize vc)
PrimitiveData::PrimitiveData(const VIL *_vil,const uint32_t vc)
{
vil=_vil;
vertex_count=vc;
vab_access=hgl_zero_new<VABAccess>(_vil->GetCount());
vab_list=hgl_zero_new<VAB *>(_vil->GetVertexAttribCount());
vab_map_list=new VABMap[_vil->GetVertexAttribCount()];
hgl_zero(ib_access);
ibo=nullptr;
}
PrimitiveData::~PrimitiveData()
{
SAFE_CLEAR_ARRAY(vab_access); //注意这里并不释放VAB在派生类中释放
delete[] vab_map_list;
delete[] vab_list; //注意这里并不释放VAB在派生类中释放
}
const int PrimitiveData::GetVABCount()const
{
return vil->GetCount();
return vil->GetVertexAttribCount();
}
const int PrimitiveData::GetVABIndex(const AnsiString &name) const
@@ -35,57 +37,79 @@ const int PrimitiveData::GetVABIndex(const AnsiString &name) const
return vil->GetIndex(name);
}
VABAccess *PrimitiveData::GetVABAccess(const int index)
VAB *PrimitiveData::GetVAB(const int index)
{
if(index<0||index>=vil->GetCount())return(nullptr);
if(index<0||index>=vil->GetVertexAttribCount())return(nullptr);
return vab_access+index;
return vab_list[index];
}
VABAccess *PrimitiveData::GetVABAccess(const AnsiString &name)
VAB *PrimitiveData::InitVAB(const int vab_index,const void *data)
{
if(name.IsEmpty())return(nullptr);
if(!vil)return(nullptr);
const int index=vil->GetIndex(name);
if(vab_index<0||vab_index>=vil->GetVertexAttribCount())
return(nullptr);
if(index<0)return(nullptr);
const VertexInputFormat *vif=vil->GetConfig(vab_index);
return vab_access+index;
if(!vif)return(nullptr);
if(!vab_list[vab_index])
{
vab_list[vab_index]=CreateVAB(vab_index,vif->format,data);
if(!vab_list[vab_index])
return(nullptr);
}
else
{
vab_map_list[vab_index].Write(data,vertex_count);
}
return vab_list[vab_index];
}
//VABAccess *SetVAB(PrimitiveData *pd,const int index,VAB *vab,VkDeviceSize start,VkDeviceSize count)
//{
// if(!pd)return(nullptr);
// if(!pd->vil)return(nullptr);
// if(index<0||index>=pd->vil->GetCount())return(nullptr);
//
// VABAccess *vaba=pd->vab_access+index;
//
// vaba->vab=vab;
// vaba->start=start;
// vaba->count=count;
//
// //#ifdef _DEBUG
// // DebugUtils *du=device->GetDebugUtils();
//
// // if(du)
// // {
// // du->SetBuffer(vab->GetBuffer(),prim_name+":VAB:Buffer:"+name);
// // du->SetDeviceMemory(vab->GetVkMemory(),prim_name+":VAB:Memory:"+name);
// // }
// //#endif//_DEBUG
//
// return vaba;
//}
VABMap *PrimitiveData::GetVABMap(const int vab_index)
{
if(vab_index<0||vab_index>=vil->GetVertexAttribCount())return nullptr;
//void SetIndexBuffer(PrimitiveData *pd,IndexBuffer *ib,const VkDeviceSize ic)
//{
// if(!pd)return;
//
// pd->ib_access.buffer=ib;
// pd->ib_access.start=0;
// pd->ib_access.count=ic;
//}
VABMap *vab_map=vab_map_list+vab_index;
if(!vab_map->IsValid())
{
if(!vab_list[vab_index])
return(nullptr);
vab_map->SetVAB(vab_list[vab_index],GetVertexOffset(),vertex_count);
}
return vab_map;
}
IndexBuffer *PrimitiveData::InitIBO(const uint32_t ic,IndexType it)
{
if(ibo)delete ibo;
ibo=CreateIBO(ic,it);
if(!ibo)
return(nullptr);
index_count=ic;
ibo_map.SetIBO(ibo,GetFirstIndex(),index_count);
return(ibo);
}
void PrimitiveData::UnmapAll()
{
for(int i=0;i<vil->GetVertexAttribCount();i++)
vab_map_list[i].Unmap();
ibo_map.Unmap();
}
namespace
{
@@ -98,90 +122,46 @@ namespace
public:
PrimitiveDataPrivateBuffer(GPUDevice *dev,const VIL *_vil,const VkDeviceSize vc):PrimitiveData(_vil,vc)
int32_t GetVertexOffset ()const override{return 0;}
uint32_t GetFirstIndex ()const override{return 0;}
VertexDataManager * GetVDM()const override{return nullptr;} ///<取得顶点数据管理器
public:
PrimitiveDataPrivateBuffer(GPUDevice *dev,const VIL *_vil,const uint32_t vc):PrimitiveData(_vil,vc)
{
device=dev;
}
~PrimitiveDataPrivateBuffer() override
{
VABAccess *vab=vab_access;
VAB **vab=vab_list;
for(uint i=0;i<vil->GetCount();i++)
for(uint i=0;i<vil->GetVertexAttribCount();i++)
{
if(vab->vab)
{
delete vab->vab;
vab->vab=nullptr;
}
if(*vab)
delete *vab;
++vab;
}
if(ib_access.buffer)
{
delete ib_access.buffer;
ib_access.buffer=nullptr;
}
if(ibo)
delete ibo;
}
IBAccess *InitIBO(const VkDeviceSize index_count,IndexType it) override
IndexBuffer *CreateIBO(const uint32_t ic,const IndexType &it) override
{
if(!device)return(nullptr);
if(ib_access.buffer)
{
delete ib_access.buffer;
ib_access.buffer=nullptr;
}
ib_access.buffer=device->CreateIBO(it,index_count);
if(!ib_access.buffer)
return(nullptr);
ib_access.start=0;
ib_access.count=index_count;
return(&ib_access);
return device->CreateIBO(it,ic);
}
VABAccess *InitVAB(const AnsiString &name,const VkFormat &format,const void *data)
VAB *CreateVAB(const int vab_index,const VkFormat format,const void *data) override
{
if(!device)return(nullptr);
if(!vil)return(nullptr);
if(name.IsEmpty())return(nullptr);
const int index=vil->GetIndex(name);
if(index<0||index>=vil->GetCount())
return(nullptr);
const VertexInputFormat *vif=vil->GetConfig(index);
if(!vif)return(nullptr);
if(vif->format!=format)
return(nullptr);
VABAccess *vaba=vab_access+index;
if(!vaba->vab)
{
vaba->vab=device->CreateVAB(format,vertex_count,data);
if(!vaba->vab)
return(nullptr);
vaba->start=0;
vaba->count=vertex_count;
}
else
{
vaba->vab->Write(data,vertex_count);
}
return vaba;
return device->CreateVAB(format,vertex_count,data);
}
};//class PrimitiveDataPrivateBuffer:public PrimitiveData
@@ -197,7 +177,13 @@ namespace
public:
PrimitiveDataVDM(VertexDataManager *_vdm,const VkDeviceSize vc):PrimitiveData(_vdm->GetVIL(),vc)
int32_t GetVertexOffset()const override { return vab_node->GetStart(); }
uint32_t GetFirstIndex ()const override { return ib_node->GetStart(); }
VertexDataManager * GetVDM()const override{return vdm;} ///<取得顶点数据管理器
public:
PrimitiveDataVDM(VertexDataManager *_vdm,const uint32_t vc):PrimitiveData(_vdm->GetVIL(),vc)
{
vdm=_vdm;
@@ -214,66 +200,37 @@ namespace
vdm->ReleaseVAB(vab_node);
}
IBAccess *InitIBO(const VkDeviceSize index_count,IndexType it) override
IndexBuffer *CreateIBO(const uint32_t ic,const IndexType &it) override
{
if(index_count<=0)return(nullptr);
if(!vdm)return(nullptr);
if(!vdm)
return(nullptr);
if(!ib_node)
{
ib_node=vdm->AcquireIB(index_count);
ib_node=vdm->AcquireIB(ic);
if(!ib_node)
return(nullptr);
ib_access.buffer=vdm->GetIBO();
ib_access.start =ib_node->GetStart();
ib_access.count =ib_node->GetCount();
}
return &ib_access;
return vdm->GetIBO();
}
VABAccess *InitVAB(const AnsiString &name,const VkFormat &format,const void *data)
VAB *CreateVAB(const int vab_index,const VkFormat format,const void *data) override
{
if(!vdm)return(nullptr);
if(!vil)return(nullptr);
if(name.IsEmpty())return(nullptr);
VAB *vab=vdm->GetVAB(vab_index);
const int index=vil->GetIndex(name);
if(!vab)return(nullptr);
if(index<0||index>=vil->GetCount())
return(nullptr);
if(data)
vab->Write(data,vab_node->GetStart(),vertex_count);
const VertexInputFormat *vif=vil->GetConfig(index);
if(!vif)return(nullptr);
if(vif->format!=format)
return(nullptr);
VABAccess *vaba=vab_access+index;
if(!vaba->vab)
{
vaba->vab=vdm->GetVAB(index);
if(!vaba->vab)
return(nullptr);
vaba->start=vab_node->GetStart();
vaba->count=vab_node->GetCount();
}
if(vaba->vab&&data)
vaba->vab->Write(data,vaba->start,vaba->count);
return vaba;
return vab;
}
};//class PrimitiveDataVDM:public PrimitiveData
}//namespace
PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const VkDeviceSize vc)
PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const uint32_t vc)
{
if(!dev)return(nullptr);
if(!_vil)return(nullptr);
@@ -282,7 +239,7 @@ PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const VkDevice
return(new PrimitiveDataPrivateBuffer(dev,_vil,vc));
}
PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const VkDeviceSize vc)
PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const uint32_t vc)
{
if(!vdm)return(nullptr);
if(vc<=0)return(nullptr);

View File

@@ -1,4 +1,7 @@
#include<hgl/graph/VK.h>
#pragma once
#include<hgl/graph/VKIndexBuffer.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
VK_NAMESPACE_BEGIN
/*
@@ -21,31 +24,50 @@ protected:
const VIL * vil;
VkDeviceSize vertex_count;
uint32_t vertex_count;
uint32_t index_count;
VABAccess *vab_access;
IBAccess ib_access;
VAB ** vab_list;
VABMap * vab_map_list;
virtual VAB * CreateVAB(const int vab_index,const VkFormat format,const void *data)=0;
protected:
IndexBuffer * ibo;
IBMap ibo_map;
virtual IndexBuffer *CreateIBO(const uint32_t ic,const IndexType &it)=0;
public:
PrimitiveData(const VIL *_vil,const VkDeviceSize vc);
PrimitiveData(const VIL *_vil,const uint32_t vc);
virtual ~PrimitiveData();
public:
const VkDeviceSize GetVertexCount ()const{return vertex_count;}
const uint32_t GetVertexCount ()const{return vertex_count;}
const int GetVABCount ()const;
const int GetVABIndex (const AnsiString &name)const;
VABAccess * GetVABAccess (const int index);
VABAccess * GetVABAccess (const AnsiString &name);
IBAccess * GetIBAccess (){return &ib_access;}
public:
VAB * GetVAB (const int index);
VAB * InitVAB (const int vab_index,const void *data);
VABMap * GetVABMap (const int vab_index);
IndexBuffer * InitIBO(const uint32_t index_count,IndexType it);
IndexBuffer * GetIBO (){return ibo;}
IBMap * GetIBMap (){return &ibo_map;}
uint32_t GetIndexCount ()const{return index_count;}
virtual int32_t GetVertexOffset ()const=0; ///<取得顶点偏移(注意是顶点不是字节)
virtual uint32_t GetFirstIndex ()const=0; ///<取得第一个索引
virtual VertexDataManager * GetVDM()const=0; ///<取得顶点数据管理器
void UnmapAll();
virtual IBAccess * InitIBO(const VkDeviceSize index_count,IndexType it)=0;
virtual VABAccess *InitVAB(const AnsiString &name,const VkFormat &format,const void *data)=0;
};//class PrimitiveData
PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const VkDeviceSize vc);
PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const VkDeviceSize vc);
PrimitiveData *CreatePrimitiveData(GPUDevice *dev,const VIL *_vil,const uint32_t vc);
PrimitiveData *CreatePrimitiveData(VertexDataManager *vdm,const uint32_t vc);
VK_NAMESPACE_END

View File

@@ -93,6 +93,30 @@ Renderable *RenderResource::CreateRenderable(Primitive *r,MaterialInstance *mi,P
return ri;
}
Renderable *RenderResource::CreateRenderable(PrimitiveCreater *pc,MaterialInstance *mi,Pipeline *p)
{
if(!p||!mi||!pc)
return(nullptr);
Primitive *prim=pc->Create();
if(!prim)
return(nullptr);
Renderable *ri=VK_NAMESPACE::CreateRenderable(prim,mi,p);
if(ri)
{
Add(prim);
Add(ri);
return ri;
}
delete prim;
return(nullptr);
}
Sampler *RenderResource::CreateSampler(VkSamplerCreateInfo *sci)
{
Sampler *s=device->CreateSampler(sci);

View File

@@ -3,44 +3,56 @@
#include<hgl/graph/VKMaterialParameters.h>
#include<hgl/graph/VKMaterial.h>
#include<hgl/graph/VKVertexAttribBuffer.h>
#include<hgl/graph/VKIndexBuffer.h>
#include<hgl/log/LogInfo.h>
VK_NAMESPACE_BEGIN
VertexInputData::VertexInputData(const uint32_t c,const uint32_t vc,const IBAccess *iba)
PrimitiveDataBuffer::PrimitiveDataBuffer(const uint32_t c,IndexBuffer *ib,VertexDataManager *_vdm)
{
binding_count=c;
vab_count=c;
buffer_list=new VkBuffer[binding_count];
buffer_offset=new VkDeviceSize[binding_count];
vab_list=hgl_zero_new<VkBuffer>(vab_count);
vab_offset=hgl_zero_new<VkDeviceSize>(vab_count);
ibo=ib;
vertex_count=vc;
if(!iba||!iba->buffer)
ib_access=nullptr;
else
ib_access=iba;
vdm=_vdm;
}
VertexInputData::~VertexInputData()
PrimitiveDataBuffer::~PrimitiveDataBuffer()
{
delete[] buffer_list;
delete[] buffer_offset;
delete[] vab_offset;
delete[] vab_list;
}
Renderable::Renderable(Primitive *r,MaterialInstance *mi,Pipeline *p,VertexInputData *vi)
const bool PrimitiveDataBuffer::Comp(const PrimitiveDataBuffer *pdb)const
{
if(!pdb)return(false);
if(vdm&&pdb->vdm)
return (vdm==pdb->vdm);
if(vab_count!=pdb->vab_count)return(false);
for(uint32_t i=0;i<vab_count;i++)
{
if(vab_list[i]!=pdb->vab_list[i])return(false);
if(vab_offset[i]!=pdb->vab_offset[i])return(false);
}
if(ibo!=pdb->ibo)
return(false);
return(true);
}
Renderable::Renderable(Primitive *r,MaterialInstance *mi,Pipeline *p,PrimitiveDataBuffer *pdb,PrimitiveRenderData *prd)
{
primitive=r;
pipeline=p;
mat_inst=mi;
vertex_input=vi;
}
Renderable::~Renderable()
{
//需要在这里添加删除pipeline/desc_sets/primitive引用计数的代码
delete vertex_input;
primitive_data_buffer=pdb;
primitive_render_data=prd;
}
Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
@@ -48,7 +60,7 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
if(!prim||!mi||!p)return(nullptr);
const VIL *vil=mi->GetVIL();
const uint32_t input_count=vil->GetCount(VertexInputGroup::Basic); //不统计Bone/LocalToWorld组的
const uint32_t input_count=vil->GetVertexAttribCount(VertexInputGroup::Basic); //不统计Bone/LocalToWorld组的
const UTF8String &mtl_name=mi->GetMaterial()->GetName();
if(prim->GetVABCount()<input_count) //小于材质要求的数量?那自然是不行的
@@ -58,49 +70,51 @@ Renderable *CreateRenderable(Primitive *prim,MaterialInstance *mi,Pipeline *p)
return(nullptr);
}
VertexInputData *vid=new VertexInputData(input_count,prim->GetVertexCount(),prim->GetIBAccess());
PrimitiveDataBuffer *pdb=new PrimitiveDataBuffer(input_count,prim->GetIBO(),prim->GetVDM());
PrimitiveRenderData *prd=new PrimitiveRenderData(prim->GetVertexCount(),prim->GetIndexCount(),prim->GetVertexOffset(),prim->GetFirstIndex());
const VertexInputFormat *vif=vil->GetVIFList(VertexInputGroup::Basic);
VABAccess *vab_access;
VAB *vab;
for(uint i=0;i<input_count;i++)
{
//注: VIF来自于材质但VAB来自于Primitive。
// 两个并不一定一样排序也不一定一样。所以不能让PRIMTIVE直接提供BUFFER_LIST/OFFSET来搞一次性绑定。
vab_access=prim->GetVABAccess(vif->name);
vab=prim->GetVAB(vif->name);
if(!vab_access||!vab_access->vab)
if(!vab)
{
LOG_ERROR("[FATAL ERROR] not found VAB \""+AnsiString(vif->name)+"\" in Material: "+mtl_name);
return(nullptr);
}
if(vab_access->vab->GetFormat()!=vif->format)
if(vab->GetFormat()!=vif->format)
{
LOG_ERROR( "[FATAL ERROR] VAB \""+UTF8String(vif->name)+
UTF8String("\" format can't match Renderable, Material(")+mtl_name+
UTF8String(") Format(")+GetVulkanFormatName(vif->format)+
UTF8String("), VAB Format(")+GetVulkanFormatName(vab_access->vab->GetFormat())+
UTF8String("), VAB Format(")+GetVulkanFormatName(vab->GetFormat())+
")");
return(nullptr);
}
if(vab_access->vab->GetStride()!=vif->stride)
if(vab->GetStride()!=vif->stride)
{
LOG_ERROR( "[FATAL ERROR] VAB \""+UTF8String(vif->name)+
UTF8String("\" stride can't match Renderable, Material(")+mtl_name+
UTF8String(") stride(")+UTF8String::numberOf(vif->stride)+
UTF8String("), VAB stride(")+UTF8String::numberOf(vab_access->vab->GetStride())+
UTF8String("), VAB stride(")+UTF8String::numberOf(vab->GetStride())+
")");
return(nullptr);
}
vid->buffer_offset[i]=vab_access->start*vif->stride;
vid->buffer_list[i]=vab_access->vab->GetBuffer();
pdb->vab_list[i]=vab->GetBuffer();
pdb->vab_offset[i]=0;
++vif;
}
return(new Renderable(prim,mi,p,vid));
return(new Renderable(prim,mi,p,pdb,prd));
}
VK_NAMESPACE_END

View File

@@ -39,7 +39,7 @@ void main()
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
vsc->AddMaterialInstanceID();
vsc->AddAssign();
vsc->SetMain(vs_main);
return(true);
}

View File

@@ -45,7 +45,7 @@ void main()
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::Color);
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::BaseColor);
fsc->AddOutput(VAT_VEC4,"FragColor"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。

View File

@@ -72,7 +72,7 @@ void main()
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::Color);
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2D,mtl::SamplerName::BaseColor);
fsc->AddOutput(VAT_VEC4,"FragColor"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。

View File

@@ -79,7 +79,7 @@ void main()
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2DArray,mtl::SamplerName::Color);
mci->AddSampler(VK_SHADER_STAGE_FRAGMENT_BIT,DescriptorSetType::PerMaterial,SamplerType::Sampler2DArray,mtl::SamplerName::BaseColor);
fsc->AddOutput(VAT_VEC4,"FragColor"); //Fragment shader的输出等于最终的RT了所以这个名称其实随便起。

View File

@@ -1,4 +1,4 @@
#include"Std2DMaterial.h"
#include"Std2DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/graph/mtl/UBOCommon.h>
@@ -14,9 +14,17 @@ bool Std2DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
const bool is_rect=(cfg->prim==Prim::SolidRectangles||cfg->prim==Prim::WireRectangles);
if(cfg->local_to_world||cfg->material_instance)
{
mci->AddStruct(SBS_LocalToWorld);
mci->AddUBO(VK_SHADER_STAGE_ALL_GRAPHICS,DescriptorSetType::PerFrame,SBS_LocalToWorld);
vsc->AddAssign();
}
if(cfg->local_to_world)
{
vsc->AddLocalToWorld();
mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS);
if(is_rect)

View File

@@ -16,7 +16,7 @@ namespace
public:
Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *cfg):Std2DMaterial(cfg)
Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *c):Std2DMaterial(c)
{
mfd=data;
}
@@ -76,9 +76,6 @@ namespace
for(auto &ua:mfd->vi)
vsc->AddInput(ua.vat,ua.name);
if(mfd->mi.mi_bytes>0)
vsc->AddMaterialInstanceID();
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
@@ -116,6 +113,9 @@ MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,Material2DCreate
if(!mfd)
return nullptr;
if(mfd->mi.mi_bytes>0)
cfg->material_instance=true;
cfg->shader_stage_flag_bit=mfd->shader_stage_flag_bit;
Std2DMaterialLoader mtl(mfd,cfg);

View File

@@ -1,4 +1,4 @@
#include"Std3DMaterial.h"
#include"Std3DMaterial.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/mtl/UBOCommon.h>
@@ -11,6 +11,15 @@ bool Std3DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
{
vsc->AddInput(cfg->position_format,VAN::Position);
if(cfg->camera||cfg->local_to_world||cfg->material_instance)
{
mci->AddStruct(SBS_LocalToWorld);
mci->AddUBO(VK_SHADER_STAGE_ALL_GRAPHICS,DescriptorSetType::PerFrame,SBS_LocalToWorld);
vsc->AddAssign();
}
if(cfg->camera)
{
mci->AddStruct(SBS_CameraInfo);
@@ -24,11 +33,20 @@ bool Std3DMaterial::CustomVertexShader(ShaderCreateInfoVertex *vsc)
{
mci->SetLocalToWorld(VK_SHADER_STAGE_ALL_GRAPHICS);
vsc->AddLocalToWorld();
vsc->AddFunction(cfg->camera?func::GetPosition3DL2WCamera:func::GetPosition3DL2W);
if(cfg->position_format.vec_size==3)
vsc->AddFunction(cfg->camera?func::GetPosition3DL2WCamera:func::GetPosition3DL2W);
else
if(cfg->position_format.vec_size==2)
vsc->AddFunction(cfg->camera?func::GetPosition3DL2WCameraBy2D:func::GetPosition3DL2WBy2D);
}
else
vsc->AddFunction(cfg->camera?func::GetPosition3DCamera:func::GetPosition3D);
{
if(cfg->position_format.vec_size==3)
vsc->AddFunction(cfg->camera?func::GetPosition3DCamera:func::GetPosition3D);
else
if(cfg->position_format.vec_size==2)
vsc->AddFunction(cfg->camera?func::GetPosition3DCameraBy2D:func::GetPosition3DBy2D);
}
if(cfg->camera
&&cfg->local_to_world)

View File

@@ -16,8 +16,8 @@ namespace
public:
Std3DMaterialLoader(material_file::MaterialFileData *data,const Material3DCreateConfig *cfg)
: Std3DMaterial(cfg)
Std3DMaterialLoader(material_file::MaterialFileData *data,const Material3DCreateConfig *c)
: Std3DMaterial(c)
{
mfd=data;
}
@@ -77,9 +77,6 @@ namespace
for(auto &ua:mfd->vi)
vsc->AddInput(ua.vat,ua.name);
if(mfd->mi.mi_bytes>0)
vsc->AddMaterialInstanceID();
if(!Std3DMaterial::CustomVertexShader(vsc))
return (false);
@@ -117,6 +114,9 @@ MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,Material3DCreate
if(!mfd)
return nullptr;
if(mfd->mi.mi_bytes>0)
cfg->material_instance=true;
cfg->shader_stage_flag_bit=mfd->shader_stage_flag_bit;
Std3DMaterialLoader mtl(mfd,cfg);

View File

@@ -172,9 +172,9 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
mi_ubo=CreateUBODescriptor(SBS_MaterialInstance,shader_stage_flag_bits);
mdi.AddUBO(shader_stage_flag_bits,DescriptorSetType::PerMaterial,mi_ubo);
mdi.AddUBO(shader_stage_flag_bits,DST_MaterialInstance,mi_ubo);
const AnsiString MI_MAX_COUNT=AnsiString::numberOf(mi_max_count);
const AnsiString MI_MAX_COUNT_STRING=AnsiString::numberOf(mi_max_count);
auto *it=shader_map.GetDataList();
@@ -182,7 +182,7 @@ bool MaterialCreateInfo::SetMaterialInstance(const AnsiString &glsl_codes,const
{
if((*it)->key&shader_stage_flag_bits)
{
(*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT);
(*it)->value->AddDefine("MI_MAX_COUNT",MI_MAX_COUNT_STRING);
(*it)->value->SetMaterialInstance(mi_ubo,mi_codes);
}
@@ -198,6 +198,28 @@ bool MaterialCreateInfo::SetLocalToWorld(const uint32_t shader_stage_flag_bits)
{
if(shader_stage_flag_bits==0)return(false);
l2w_max_count=hgl_min<uint32_t>(ubo_range/sizeof(Matrix4f),HGL_U16_MAX);
mdi.AddStruct(SBS_LocalToWorld);
l2w_ubo=CreateUBODescriptor(SBS_LocalToWorld,shader_stage_flag_bits);
mdi.AddUBO(shader_stage_flag_bits,DST_LocalToWorld,l2w_ubo);
const AnsiString L2W_MAX_COUNT_STRING=AnsiString::numberOf(l2w_max_count);
auto *it=shader_map.GetDataList();
for(int i=0;i<shader_map.GetCount();i++)
{
if((*it)->key&shader_stage_flag_bits)
{
(*it)->value->AddDefine("L2W_MAX_COUNT",L2W_MAX_COUNT_STRING);
}
++it;
}
l2w_shader_stage=shader_stage_flag_bits;
return(true);

View File

@@ -156,10 +156,11 @@ bool ShaderCreateInfo::ProcSubpassInput()
namespace
{
constexpr const char MF_GetMI_VS []="\nMaterialInstance GetMI(){return mtl.mi[MaterialInstanceID];}\n";
constexpr const char MI_ID_OUTPUT[]="MaterialInstanceID";
constexpr const char MF_GetMI_VS []="\nMaterialInstance GetMI(){return mtl.mi[Assign.y];}\n";
constexpr const char MF_GetMI_Other []="\nMaterialInstance GetMI(){return mtl.mi[Input.MaterialInstanceID];}\n";
constexpr const char MF_HandoverMI_VS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=MaterialInstanceID;}\n";
constexpr const char MF_HandoverMI_VS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Assign.y;}\n";
constexpr const char MF_HandoverMI_GS[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Input[0].MaterialInstanceID;}\n";
constexpr const char MF_HandoverMI_OTHER[]= "\nvoid HandoverMI(){Output.MaterialInstanceID=Input.MaterialInstanceID;}\n";
}//namespace
@@ -176,7 +177,7 @@ void ShaderCreateInfo::SetMaterialInstance(UBODescriptor *ubo,const AnsiString &
void ShaderCreateInfo::AddMaterialInstanceOutput()
{
AddOutput(VAT_UINT,mtl::func::MaterialInstanceID,Interpolation::Flat);
AddOutput(VAT_UINT,MI_ID_OUTPUT,Interpolation::Flat);
if(shader_stage==VK_SHADER_STAGE_VERTEX_BIT) AddFunction(MF_HandoverMI_VS);else
if(shader_stage==VK_SHADER_STAGE_GEOMETRY_BIT) AddFunction(MF_HandoverMI_GS);else

View File

@@ -1,4 +1,4 @@
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
#include<hgl/shadergen/ShaderCreateInfoVertex.h>
#include<hgl/shadergen/ShaderDescriptorInfo.h>
#include<hgl/graph/VertexAttrib.h>
#include<hgl/graph/VKShaderStage.h>
@@ -48,41 +48,14 @@ void ShaderCreateInfoVertex::AddJoint()
AddInput(VAT_VEC4, VAN::JointWeight,VK_VERTEX_INPUT_RATE_VERTEX,VertexInputGroup::JointWeight);
}
namespace
void ShaderCreateInfoVertex::AddAssign()
{
constexpr const char MF_GetLocalToWorld_ByID[]="\nmat4 GetLocalToWorld(){return l2w.mats[LocalToWorld_ID];}\n";
constexpr const char MF_GetLocalToWorld_by4VI[]=R"(
mat4 GetLocalToWorld()
{
return mat4(LocalToWorld_0,
LocalToWorld_1,
LocalToWorld_2,
LocalToWorld_3);
}
)";
}
void ShaderCreateInfoVertex::AddLocalToWorld()
{
char name[]= "LocalToWorld_?";
for(uint i=0;i<4;i++)
{
name[sizeof(name)-2]='0'+i;
AddInput(VAT_VEC4,name,VK_VERTEX_INPUT_RATE_INSTANCE,VertexInputGroup::LocalToWorld);
}
AddFunction(MF_GetLocalToWorld_by4VI);
}
void ShaderCreateInfoVertex::AddMaterialInstanceID()
{
AddInput( MI_VAT_FMT,
MI_VIS_NAME,
AddInput( ASSIGN_VAT_FMT,
ASSIGN_VIS_NAME,
VK_VERTEX_INPUT_RATE_INSTANCE,
VertexInputGroup::MaterialInstanceID);
VertexInputGroup::Assign);
AddFunction(STD_MTL_FUNC_NAMESPACE::MF_GetLocalToWorld_ByAssign);
}
bool ShaderCreateInfoVertex::ProcInput(ShaderCreateInfo *)

View File

@@ -2,21 +2,11 @@
#include<hgl/graph/mtl/StdMaterial.h>
STD_MTL_NAMESPACE_BEGIN
namespace func
{
STD_MTL_FUNC_NAMESPACE_BEGIN
//C++端使用一个RG8UI或RGB16UI格式的顶点输入流来传递Assign数据其中x为LocalToWorld IDy为MaterialInstance ID
constexpr const char MaterialInstanceID[]="MaterialInstanceID";
constexpr const char MF_GetLocalToWorld_ByAssign[]= "\nmat4 GetLocalToWorld(){return l2w.mats[Assign.x];}\n";
constexpr const char GetLocalToWorld[]=R"(
mat4 GetLocalToWorld()
{
return mat4(LocalToWorld_0,
LocalToWorld_1,
LocalToWorld_2,
LocalToWorld_3);
}
)";
}//namespace func
STD_MTL_NAMESPACE_END
constexpr const char MF_GetMaterialInstance_ByAssign[]= "\nMaterialInstance GetMaterialInstance(){return mi_set[Assign.y];}\n";
STD_MTL_FUNC_NAMESPACE_END

View File

@@ -1,4 +1,4 @@
#pragma once
#pragma once
#include<hgl/graph/mtl/StdMaterial.h>
#include<hgl/graph/CoordinateSystem.h>
@@ -7,78 +7,26 @@ namespace func
{
constexpr const char *GetPosition2D[size_t(CoordinateSystem2D::RANGE_SIZE)]=
{
R"(
vec4 GetPosition2D()
{
return vec4(Position,0,1);
}
)",
R"(
vec4 GetPosition2D()
{
return vec4(Position.xy*2-1,0,1);
}
)",
R"(
vec4 GetPosition2D()
{
return viewport.ortho_matrix*vec4(Position,0,1);
}
)"
"vec4 GetPosition2D(){return vec4(Position,0,1);}", //NDC
"vec4 GetPosition2D(){return vec4(Position.xy*2-1,0,1);}", //ZeroToOne
"vec4 GetPosition2D(){return viewport.ortho_matrix*vec4(Position,0,1);}" //Ortho
};
constexpr const char *GetPosition2DL2W[size_t(CoordinateSystem2D::RANGE_SIZE)]=
{
R"(
vec4 GetPosition2D()
{
return GetLocalToWorld()*vec4(Position,0,1);
}
)",
R"(
vec4 GetPosition2D()
{
return GetLocalToWorld()*vec4(Position.xy*2-1,0,1);
}
)",
R"(
vec4 GetPosition2D()
{
return GetLocalToWorld()*viewport.ortho_matrix*vec4(Position,0,1);
}
)"
"vec4 GetPosition2D(){return GetLocalToWorld()*vec4(Position,0,1);}", //NDC
"vec4 GetPosition2D(){return GetLocalToWorld()*vec4(Position.xy*2-1,0,1);}", //ZeroToOne
"vec4 GetPosition2D(){return GetLocalToWorld()*viewport.ortho_matrix*vec4(Position,0,1);}" //Ortho
};
constexpr const char *GetPosition3D=R"(
vec4 GetPosition3D()
{
return vec4(Position,1);
}
)";
constexpr const char *GetPosition3D ="vec4 GetPosition3D(){return vec4(Position,1);}";
constexpr const char *GetPosition3DL2W ="vec4 GetPosition3D(){return GetLocalToWorld()*vec4(Position,1);}";
constexpr const char *GetPosition3DCamera ="vec4 GetPosition3D(){return camera.vp*vec4(Position,1);}";
constexpr const char *GetPosition3DL2WCamera ="vec4 GetPosition3D(){return camera.vp*GetLocalToWorld()*vec4(Position,1);}";
constexpr const char *GetPosition3DL2W=R"(
vec4 GetPosition3D()
{
return GetLocalToWorld()*vec4(Position,1);
}
)";
constexpr const char *GetPosition3DCamera=R"(
vec4 GetPosition3D()
{
return camera.vp*vec4(Position,1);
}
)";
constexpr const char *GetPosition3DL2WCamera=R"(
vec4 GetPosition3D()
{
return camera.vp*GetLocalToWorld()*vec4(Position,1);
}
)";
constexpr const char *GetPosition3DBy2D ="vec4 GetPosition3D(){return vec4(Position,0,1);}";
constexpr const char *GetPosition3DL2WBy2D ="vec4 GetPosition3D(){return GetLocalToWorld()*vec4(Position,0,1);}";
constexpr const char *GetPosition3DCameraBy2D ="vec4 GetPosition3D(){return camera.vp*vec4(Position,0,1);}";
constexpr const char *GetPosition3DL2WCameraBy2D="vec4 GetPosition3D(){return camera.vp*GetLocalToWorld()*vec4(Position,0,1);}";
}//namespace func
STD_MTL_NAMESPACE_END