Merge branch 'devel_27_Default3DMaterial' of http://www.hyzgame.com:3000/hyzboy/ULRE into devel_27_Default3DMaterial

This commit is contained in:
HuYingzhuo(hugo/hyzboy) 2023-10-10 09:49:59 +08:00
commit 019e9964fa
7 changed files with 343 additions and 84 deletions

2
CMCore

@ -1 +1 @@
Subproject commit 252f2f6a1f4546d84e105e9f76462576e1b26a25 Subproject commit d5264e1da655390bdef2ce99550024c69b7c4cb1

View File

@ -37,13 +37,13 @@ namespace hgl
protected: protected:
virtual bool BeginCustomShader(){return true;/*some work before creating shader*/}; virtual bool BeginCustomShader(){return true;/*some work before create shader*/};
virtual bool CustomVertexShader(ShaderCreateInfoVertex *)=0; virtual bool CustomVertexShader(ShaderCreateInfoVertex *)=0;
virtual bool CustomGeometryShader(ShaderCreateInfoGeometry *){return false;} virtual bool CustomGeometryShader(ShaderCreateInfoGeometry *){return false;}
virtual bool CustomFragmentShader(ShaderCreateInfoFragment *)=0; virtual bool CustomFragmentShader(ShaderCreateInfoFragment *)=0;
virtual bool EndCustomShader(){return true;/*some work after creating shader*/}; virtual bool EndCustomShader(){return true;/*some work after create shader*/};
public: public:
@ -52,9 +52,6 @@ namespace hgl
virtual MaterialCreateInfo *Create(); virtual MaterialCreateInfo *Create();
};//class StdMaterial };//class StdMaterial
bool LoadMaterialFromFile(const AnsiString &mtl_filename);
}//namespace mtl }//namespace mtl
}//namespace graph }//namespace graph
}//namespace hgl }//namespace hgl

View File

@ -88,6 +88,10 @@ public:
void SetLocalToWorld(UBODescriptor *); void SetLocalToWorld(UBODescriptor *);
void SetMain(const AnsiString &str){main_function=str;} void SetMain(const AnsiString &str){main_function=str;}
void SetMain(const char *str,const int len)
{
main_function.SetString(str,len);
}
const AnsiString &GetOutputStruct()const{return output_struct;} const AnsiString &GetOutputStruct()const{return output_struct;}
const AnsiString &GetShaderSource()const{return final_shader;} const AnsiString &GetShaderSource()const{return final_shader;}

View File

@ -1,24 +1,122 @@
#include"Std2DMaterial.h" #include"Std2DMaterial.h"
#include"MaterialFileData.h"
#include<hgl/shadergen/MaterialCreateInfo.h>
STD_MTL_NAMESPACE_BEGIN STD_MTL_NAMESPACE_BEGIN
class Std2DMaterialLoader:public Std2DMaterial
namespace
{ {
public: class Std2DMaterialLoader:public Std2DMaterial
{
protected:
using Std2DMaterial::Std2DMaterial; material_file::MaterialFileData *mfd;
~Std2DMaterialLoader()=default;
bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override{return true;} public:
bool CustomGeometryShader(ShaderCreateInfoGeometry *) override{return true;}
bool CustomFragmentShader(ShaderCreateInfoFragment *) override{return true;}
bool EndCustomShader() override{return true;} Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *cfg):Std2DMaterial(cfg)
};//class Std2DMaterialLoader:public Std2DMaterial {
mfd=data;
}
~Std2DMaterialLoader()
{
delete mfd;
}
bool BeginCustomShader() override
{
if(!Std2DMaterial::BeginCustomShader())
return(false);
if(mfd->mi.mi_bytes>0)
{
mci->SetMaterialInstance( mfd->mi.code,
mfd->mi.mi_bytes,
mfd->mi.shader_stage_flag_bits);
return(false);
}
return true;
}
bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override
{
if(!Std2DMaterial::CustomVertexShader(vsc))
return(false);
if(mfd->vi.GetCount()>0)
{
for(auto &ua:mfd->vi)
vsc->AddInput(ua.vat,ua.name);
}
material_file::ShaderData *sd=mfd->shader[VK_SHADER_STAGE_VERTEX_BIT];
if(!sd)
return(false);
for(auto &ua:sd->output)
vsc->AddOutput(ua.vat,ua.name);
vsc->SetMain(sd->code,sd->code_length); //这里会产生复制这个string但我不希望产生这个。未来想办法改进
return true;
}
bool CustomGeometryShader(ShaderCreateInfoGeometry *gsc) override
{
if(!Std2DMaterial::CustomGeometryShader(gsc))
return(false);
material_file::GeometryShaderData *sd=(material_file::GeometryShaderData *)(mfd->shader[VK_SHADER_STAGE_GEOMETRY_BIT]);
if(!sd)
return(false);
gsc->SetGeom(sd->input_prim,sd->output_prim,sd->max_vertices);
for(auto &ua:sd->output)
gsc->AddOutput(ua.vat,ua.name);
gsc->SetMain(sd->code,sd->code_length); //这里会产生复制这个string但我不希望产生这个。未来想办法改进
return true;
}
bool CustomFragmentShader(ShaderCreateInfoFragment *fsc) override
{
if(!Std2DMaterial::CustomFragmentShader(fsc))
return(false);
material_file::ShaderData *sd=mfd->shader[VK_SHADER_STAGE_FRAGMENT_BIT];
if(!sd)
return(false);
for(auto &ua:sd->output)
fsc->AddOutput(ua.vat,ua.name);
fsc->SetMain(sd->code,sd->code_length); //这里会产生复制这个string但我不希望产生这个。未来想办法改进
return true;
}
bool EndCustomShader() override{return true;}
};//class Std2DMaterialLoader:public Std2DMaterial
}//namespace
material_file::MaterialFileData *LoadMaterialDataFromFile(const AnsiString &mtl_filename);
MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const Material2DCreateConfig *cfg) MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const Material2DCreateConfig *cfg)
{ {
Std2DMaterialLoader *mtl=new Std2DMaterialLoader(cfg); material_file::MaterialFileData *mfd=LoadMaterialDataFromFile(name);
return nullptr; if(!mfd)
return nullptr;
Std2DMaterialLoader mtl(mfd,cfg);
return mtl.Create();
} }
STD_MTL_NAMESPACE_END STD_MTL_NAMESPACE_END

View File

@ -72,6 +72,7 @@ SET(STD_MTL_SOURCE ${STD_MTL_HEADER_PATH}/MaterialConfig.h
${STD_MTL_HEADER_PATH}/StdMaterial.h ${STD_MTL_HEADER_PATH}/StdMaterial.h
${STD_MTL_HEADER_PATH}/ShaderBuffer.h ${STD_MTL_HEADER_PATH}/ShaderBuffer.h
StandardMaterial.cpp StandardMaterial.cpp
MaterialFileData.h
MaterialFileLoader.cpp) MaterialFileLoader.cpp)
SOURCE_GROUP("Standard Material" FILES ${STD_MTL_SOURCE}) SOURCE_GROUP("Standard Material" FILES ${STD_MTL_SOURCE})

View File

@ -0,0 +1,92 @@
#pragma once
#include<hgl/type/Map.h>
#include<hgl/graph/VKShaderStage.h>
namespace material_file
{
using namespace hgl;
using namespace hgl::graph;
struct UniformAttrib
{
VAT vat;
char name[SHADER_RESOURCE_NAME_MAX_LENGTH];
};
struct MaterialInstanceData
{
const char *code;
uint code_length;
uint mi_bytes;
uint32_t shader_stage_flag_bits;
};
struct ShaderData
{
VkShaderStageFlagBits shader_stage;
const char *code;
uint code_length;
List<UniformAttrib> output;
public:
ShaderData(VkShaderStageFlagBits ss)
{
shader_stage=ss;
code=nullptr;
code_length=0;
}
const VkShaderStageFlagBits GetShaderStage()const{return shader_stage;}
};
struct GeometryShaderData:public ShaderData
{
Prim input_prim;
Prim output_prim;
uint max_vertices=0;
public:
using ShaderData::ShaderData;
};
struct MaterialFileData
{
private:
//不管是文本版还是二进制版
//其中的代码段数据解析后都是放的指针,并无复制出来。
//所以这里需要保存原始的文件数据
char * data=nullptr;
int data_length=0;
public:
MaterialInstanceData mi{};
List<UniformAttrib> vi;
ObjectMap<VkShaderStageFlagBits,ShaderData> shader;
public:
MaterialFileData(char *d,int dl)
{
data=d;
data_length=dl;
}
~MaterialFileData()
{
delete[] data;
}
};//struct MaterialFileData
}//namespace material_file

View File

@ -1,17 +1,20 @@
#include<hgl/graph/mtl/MaterialConfig.h> #include<hgl/graph/mtl/MaterialConfig.h>
#include<hgl/graph/mtl/Material2DCreateConfig.h> #include<hgl/graph/mtl/Material2DCreateConfig.h>
#include<hgl/graph/mtl/Material3DCreateConfig.h> #include<hgl/graph/mtl/Material3DCreateConfig.h>
#include<hgl/graph/VKShaderStage.h> #include<hgl/graph/VKShaderStage.h>
#include<hgl/graph/VertexAttrib.h>
#include<hgl/io/TextInputStream.h> #include<hgl/io/TextInputStream.h>
#include<hgl/io/FileInputStream.h>
#include<hgl/filesystem/FileSystem.h> #include<hgl/filesystem/FileSystem.h>
#include"MaterialFileData.h"
STD_MTL_NAMESPACE_BEGIN STD_MTL_NAMESPACE_BEGIN
namespace namespace
{ {
using TextParse=io::TextInputStream::ParseCallback<char>; using namespace material_file;
using MaterialFileParse=io::TextInputStream::ParseCallback<char>;
enum class MaterialFileBlock enum class MaterialFileBlock
{ {
@ -30,8 +33,8 @@ namespace
struct MaterialFileBlockInfo struct MaterialFileBlockInfo
{ {
const char *name; char *name;
const int len; int len;
MaterialFileBlock state; MaterialFileBlock state;
}; };
@ -59,7 +62,7 @@ namespace
return MaterialFileBlock::None; return MaterialFileBlock::None;
} }
struct MaterialFileBlockParse:public TextParse struct MaterialFileBlockParse:public MaterialFileParse
{ {
MaterialFileBlock state; MaterialFileBlock state;
@ -68,7 +71,7 @@ namespace
state=MaterialFileBlock::None; state=MaterialFileBlock::None;
} }
bool OnLine(const char *text,const int len) override bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -77,14 +80,14 @@ namespace
} }
};//struct MaterialFileBlockParse };//struct MaterialFileBlockParse
struct CodeParse:public TextParse struct CodeParse:public MaterialFileParse
{ {
const char *start =nullptr; char *start =nullptr;
const char *end =nullptr; char *end =nullptr;
public: public:
bool OnLine(const char *text,const int len) override bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -100,6 +103,7 @@ namespace
if(*text=='}') if(*text=='}')
{ {
*text=0;
end=text; end=text;
return(true); return(true);
} }
@ -108,7 +112,7 @@ namespace
} }
};//struct CodeParse };//struct CodeParse
struct MaterialInstanceStateParse:public TextParse struct MaterialInstanceStateParse:public MaterialFileParse
{ {
bool code =false; bool code =false;
CodeParse code_parse; CodeParse code_parse;
@ -116,9 +120,27 @@ namespace
uint mi_bytes =0; uint mi_bytes =0;
uint32_t shader_stage_flag_bits =0; uint32_t shader_stage_flag_bits =0;
MaterialInstanceData *mid=nullptr;
public: public:
bool OnLine(const char *text,const int len) override MaterialInstanceStateParse(MaterialInstanceData *d)
{
mid=d;
}
~MaterialInstanceStateParse()
{
if(code_parse.start&&code_parse.end)
{
mid->code =code_parse.start;
mid->code_length =code_parse.end-code_parse.start;
mid->mi_bytes =mi_bytes;
mid->shader_stage_flag_bits =shader_stage_flag_bits;
}
}
bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -170,13 +192,6 @@ namespace
} }
};//struct MaterialInstanceStateParse };//struct MaterialInstanceStateParse
struct UniformAttrib
{
VAT vat;
char name[SHADER_RESOURCE_NAME_MAX_LENGTH];
};
bool ParseUniformAttrib(UniformAttrib *ua,const char *str) bool ParseUniformAttrib(UniformAttrib *ua,const char *str)
{ {
const char *sp; const char *sp;
@ -198,13 +213,18 @@ namespace
return(true); return(true);
} }
struct VertexInputBlockParse:public TextParse struct VertexInputBlockParse:public MaterialFileParse
{ {
List<UniformAttrib> input_list; List<UniformAttrib> *vi_list=nullptr;
public: public:
bool OnLine(const char *text,const int len) override VertexInputBlockParse(List<UniformAttrib> *ual)
{
vi_list=ual;
}
bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -212,23 +232,29 @@ namespace
UniformAttrib ua; UniformAttrib ua;
if(ParseUniformAttrib(&ua,text)) if(ParseUniformAttrib(&ua,text))
input_list.Add(ua); vi_list->Add(ua);
return(true); return(true);
} }
};//struct VertexInputBlockParse };//struct VertexInputBlockParse
struct ShaderBlockParse:public TextParse struct ShaderBlockParse:public MaterialFileParse
{ {
ShaderData * shader_data=nullptr;
bool output=false; bool output=false;
List<UniformAttrib> output_list;
bool code=false; bool code=false;
CodeParse code_parse; CodeParse code_parse;
public: public:
bool OnLine(const char *text,const int len) override ShaderBlockParse(ShaderData *sd)
{
shader_data=sd;
}
bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -236,8 +262,13 @@ namespace
if(code) if(code)
{ {
if(code_parse.OnLine(text,len)) if(code_parse.OnLine(text,len))
{
code=false; code=false;
shader_data->code=code_parse.start;
shader_data->code_length=code_parse.end-code_parse.start;
}
return(true); return(true);
} }
@ -252,7 +283,7 @@ namespace
UniformAttrib ua; UniformAttrib ua;
if(ParseUniformAttrib(&ua,text)) if(ParseUniformAttrib(&ua,text))
output_list.Add(ua); shader_data->output.Add(ua);
} }
if(hgl::stricmp(text,"Code",4)==0) if(hgl::stricmp(text,"Code",4)==0)
@ -271,13 +302,16 @@ namespace
struct GeometryShaderBlockParse:public ShaderBlockParse struct GeometryShaderBlockParse:public ShaderBlockParse
{ {
Prim input_prim; GeometryShaderData *gsd=nullptr;
Prim output_prim;
uint max_vertices;
public: public:
bool OnLine(const char *text,const int len) override GeometryShaderBlockParse(GeometryShaderData *sd):ShaderBlockParse(sd)
{
gsd=sd;
}
bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -297,7 +331,7 @@ namespace
if(!CheckGeometryShaderIn(ip)) if(!CheckGeometryShaderIn(ip))
return(false); return(false);
input_prim=ip; gsd->input_prim=ip;
return(true); return(true);
} }
else else
@ -316,15 +350,15 @@ namespace
if(!CheckGeometryShaderOut(op)) if(!CheckGeometryShaderOut(op))
return(false); return(false);
output_prim=op; gsd->output_prim=op;
while(*text!=',')++text; while(*text!=',')++text;
while(*text==' '||*text=='\t'||*text==',')++text; while(*text==' '||*text=='\t'||*text==',')++text;
hgl::stou(text,max_vertices); hgl::stou(text,gsd->max_vertices);
if(max_vertices<=0) if(gsd->max_vertices<=0)
return(false); return(false);
return(true); return(true);
@ -338,26 +372,30 @@ namespace
};//struct GeometryShaderBlockParse };//struct GeometryShaderBlockParse
struct MaterialFileParse:public TextParse struct MaterialTextParse:public MaterialFileParse
{ {
MaterialFileBlock state; MaterialFileBlock state;
TextParse *parse; MaterialFileParse *parse;
MaterialFileData *mfd;
public: public:
MaterialFileParse() MaterialTextParse(MaterialFileData *fd)
{ {
state=MaterialFileBlock::None; state=MaterialFileBlock::None;
parse=nullptr; parse=nullptr;
mfd=fd;
} }
~MaterialFileParse() ~MaterialTextParse()
{ {
SAFE_CLEAR(parse) SAFE_CLEAR(parse)
} }
bool OnLine(const char *text,const int len) override bool OnLine(char *text,const int len) override
{ {
if(!text||!*text||len<=0) if(!text||!*text||len<=0)
return(false); return(false);
@ -368,16 +406,50 @@ namespace
state=GetMaterialFileState(text+1,len-1); state=GetMaterialFileState(text+1,len-1);
switch(state) if(state==MaterialFileBlock::Material)
parse=new MaterialFileBlockParse;
else
if(state==MaterialFileBlock::MaterialInstance)
parse=new MaterialInstanceStateParse(&(mfd->mi));
else
if(state==MaterialFileBlock::VertexInput)
parse=new VertexInputBlockParse(&(mfd->vi));
else
if(state>=MaterialFileBlock::Vertex
&&state<=MaterialFileBlock::Fragment)
{ {
case MaterialFileBlock::Material: parse=new MaterialFileBlockParse;break; ShaderData *sd=nullptr;
case MaterialFileBlock::MaterialInstance: parse=new MaterialInstanceStateParse;break;
case MaterialFileBlock::VertexInput: parse=new VertexInputBlockParse;break;
case MaterialFileBlock::Vertex:
case MaterialFileBlock::Fragment: parse=new ShaderBlockParse;break;
case MaterialFileBlock::Geometry: parse=new GeometryShaderBlockParse;break;
default: state=MaterialFileBlock::None;return(false); if(state==MaterialFileBlock::Vertex)
{
sd=new ShaderData(VK_SHADER_STAGE_VERTEX_BIT);
parse=new ShaderBlockParse(sd);
}
else
if(state==MaterialFileBlock::Geometry)
{
sd=new GeometryShaderData(VK_SHADER_STAGE_GEOMETRY_BIT);
parse=new GeometryShaderBlockParse((GeometryShaderData *)sd);
}
else
if(state==MaterialFileBlock::Fragment)
{
sd=new ShaderData(VK_SHADER_STAGE_FRAGMENT_BIT);
parse=new ShaderBlockParse(sd);
}
if(!sd)
return(false);
mfd->shader.Add(sd->GetShaderStage(),sd);
}
else
{
state=MaterialFileBlock::None;
return(false);
} }
return(true); return(true);
@ -391,35 +463,30 @@ namespace
}; };
}//namespace MaterialFile }//namespace MaterialFile
bool LoadMaterialFromFile(const AnsiString &mtl_filename) MaterialFileData *LoadMaterialDataFromFile(const AnsiString &mtl_filename)
{ {
const OSString mtl_osfn=ToOSString(mtl_filename+".mtl"); const OSString mtl_osfn=ToOSString(mtl_filename+".mtl");
const OSString mtl_os_filename=filesystem::MergeFilename(OS_TEXT("ShaderLibrary"),mtl_osfn); const OSString mtl_os_filename=filesystem::MergeFilename(OS_TEXT("ShaderLibrary"),mtl_osfn);
if(!filesystem::FileExist(mtl_os_filename)) if(!filesystem::FileExist(mtl_os_filename))
return(false); return nullptr;
io::OpenFileInputStream fis(mtl_os_filename); char *data; //未来二进制版本的材质文件也是使用LoadFileToMemory加载。这里为了统一所以文本也这么操作。
if(!fis) int size=filesystem::LoadFileToMemory(mtl_os_filename,(void **)&data,true);
return(false);
MaterialFileParse mtp; MaterialFileData *mfd=new MaterialFileData(data,size);
io::TextInputStream tis(fis,0); MaterialTextParse mtp(mfd);
io::TextInputStream tis(data,size);
tis.SetParseCallback(&mtp); tis.SetParseCallback(&mtp);
return tis.Run(); if(!tis.Run())
} return nullptr;
MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const MaterialCreateConfig *cfg) return mfd;
{
return nullptr;
} }
//MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const Material3DCreateConfig *cfg)
//{
//}
STD_MTL_NAMESPACE_END STD_MTL_NAMESPACE_END