diff --git a/CMCore b/CMCore index 252f2f6a..d5264e1d 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit 252f2f6a1f4546d84e105e9f76462576e1b26a25 +Subproject commit d5264e1da655390bdef2ce99550024c69b7c4cb1 diff --git a/inc/hgl/graph/mtl/StdMaterial.h b/inc/hgl/graph/mtl/StdMaterial.h index 0f7e0e8b..27abeda4 100644 --- a/inc/hgl/graph/mtl/StdMaterial.h +++ b/inc/hgl/graph/mtl/StdMaterial.h @@ -37,13 +37,13 @@ namespace hgl 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 CustomGeometryShader(ShaderCreateInfoGeometry *){return false;} 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: @@ -52,9 +52,6 @@ namespace hgl virtual MaterialCreateInfo *Create(); };//class StdMaterial - - - bool LoadMaterialFromFile(const AnsiString &mtl_filename); }//namespace mtl }//namespace graph }//namespace hgl diff --git a/inc/hgl/shadergen/ShaderCreateInfo.h b/inc/hgl/shadergen/ShaderCreateInfo.h index 4823a941..6a26628d 100644 --- a/inc/hgl/shadergen/ShaderCreateInfo.h +++ b/inc/hgl/shadergen/ShaderCreateInfo.h @@ -88,6 +88,10 @@ public: void SetLocalToWorld(UBODescriptor *); 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 &GetShaderSource()const{return final_shader;} diff --git a/src/ShaderGen/2d/Std2DMaterialLoader.cpp b/src/ShaderGen/2d/Std2DMaterialLoader.cpp index 959a13b7..f968f463 100644 --- a/src/ShaderGen/2d/Std2DMaterialLoader.cpp +++ b/src/ShaderGen/2d/Std2DMaterialLoader.cpp @@ -1,24 +1,122 @@ -#include"Std2DMaterial.h" +#include"Std2DMaterial.h" +#include"MaterialFileData.h" +#include STD_MTL_NAMESPACE_BEGIN -class Std2DMaterialLoader:public Std2DMaterial + +namespace { -public: + class Std2DMaterialLoader:public Std2DMaterial + { + protected: - using Std2DMaterial::Std2DMaterial; - ~Std2DMaterialLoader()=default; + material_file::MaterialFileData *mfd; - bool CustomVertexShader(ShaderCreateInfoVertex *vsc) override{return true;} - bool CustomGeometryShader(ShaderCreateInfoGeometry *) override{return true;} - bool CustomFragmentShader(ShaderCreateInfoFragment *) override{return true;} + public: - bool EndCustomShader() override{return true;} -};//class Std2DMaterialLoader:public Std2DMaterial + Std2DMaterialLoader(material_file::MaterialFileData *data,const Material2DCreateConfig *cfg):Std2DMaterial(cfg) + { + 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) { - 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 diff --git a/src/ShaderGen/CMakeLists.txt b/src/ShaderGen/CMakeLists.txt index f078ffb9..1983f227 100644 --- a/src/ShaderGen/CMakeLists.txt +++ b/src/ShaderGen/CMakeLists.txt @@ -72,6 +72,7 @@ SET(STD_MTL_SOURCE ${STD_MTL_HEADER_PATH}/MaterialConfig.h ${STD_MTL_HEADER_PATH}/StdMaterial.h ${STD_MTL_HEADER_PATH}/ShaderBuffer.h StandardMaterial.cpp + MaterialFileData.h MaterialFileLoader.cpp) SOURCE_GROUP("Standard Material" FILES ${STD_MTL_SOURCE}) diff --git a/src/ShaderGen/MaterialFileData.h b/src/ShaderGen/MaterialFileData.h new file mode 100644 index 00000000..06250f66 --- /dev/null +++ b/src/ShaderGen/MaterialFileData.h @@ -0,0 +1,92 @@ +#pragma once +#include +#include + +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 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 vi; + + ObjectMap shader; + + public: + + MaterialFileData(char *d,int dl) + { + data=d; + data_length=dl; + } + + ~MaterialFileData() + { + delete[] data; + } + };//struct MaterialFileData +}//namespace material_file diff --git a/src/ShaderGen/MaterialFileLoader.cpp b/src/ShaderGen/MaterialFileLoader.cpp index 6e11f98d..f53665ba 100644 --- a/src/ShaderGen/MaterialFileLoader.cpp +++ b/src/ShaderGen/MaterialFileLoader.cpp @@ -1,17 +1,20 @@ -#include +#include #include #include #include -#include #include -#include #include +#include"MaterialFileData.h" + STD_MTL_NAMESPACE_BEGIN + namespace { - using TextParse=io::TextInputStream::ParseCallback; + using namespace material_file; + + using MaterialFileParse=io::TextInputStream::ParseCallback; enum class MaterialFileBlock { @@ -30,8 +33,8 @@ namespace struct MaterialFileBlockInfo { - const char *name; - const int len; + char *name; + int len; MaterialFileBlock state; }; @@ -59,7 +62,7 @@ namespace return MaterialFileBlock::None; } - struct MaterialFileBlockParse:public TextParse + struct MaterialFileBlockParse:public MaterialFileParse { MaterialFileBlock state; @@ -68,7 +71,7 @@ namespace 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) return(false); @@ -77,14 +80,14 @@ namespace } };//struct MaterialFileBlockParse - struct CodeParse:public TextParse + struct CodeParse:public MaterialFileParse { - const char *start =nullptr; - const char *end =nullptr; + char *start =nullptr; + char *end =nullptr; public: - bool OnLine(const char *text,const int len) override + bool OnLine(char *text,const int len) override { if(!text||!*text||len<=0) return(false); @@ -100,6 +103,7 @@ namespace if(*text=='}') { + *text=0; end=text; return(true); } @@ -108,7 +112,7 @@ namespace } };//struct CodeParse - struct MaterialInstanceStateParse:public TextParse + struct MaterialInstanceStateParse:public MaterialFileParse { bool code =false; CodeParse code_parse; @@ -116,9 +120,27 @@ namespace uint mi_bytes =0; uint32_t shader_stage_flag_bits =0; + MaterialInstanceData *mid=nullptr; + 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) return(false); @@ -170,13 +192,6 @@ namespace } };//struct MaterialInstanceStateParse - struct UniformAttrib - { - VAT vat; - - char name[SHADER_RESOURCE_NAME_MAX_LENGTH]; - }; - bool ParseUniformAttrib(UniformAttrib *ua,const char *str) { const char *sp; @@ -198,13 +213,18 @@ namespace return(true); } - struct VertexInputBlockParse:public TextParse + struct VertexInputBlockParse:public MaterialFileParse { - List input_list; + List *vi_list=nullptr; public: - bool OnLine(const char *text,const int len) override + VertexInputBlockParse(List *ual) + { + vi_list=ual; + } + + bool OnLine(char *text,const int len) override { if(!text||!*text||len<=0) return(false); @@ -212,23 +232,29 @@ namespace UniformAttrib ua; if(ParseUniformAttrib(&ua,text)) - input_list.Add(ua); + vi_list->Add(ua); return(true); } };//struct VertexInputBlockParse - struct ShaderBlockParse:public TextParse + struct ShaderBlockParse:public MaterialFileParse { + ShaderData * shader_data=nullptr; + bool output=false; - List output_list; bool code=false; CodeParse code_parse; 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) return(false); @@ -236,8 +262,13 @@ namespace if(code) { if(code_parse.OnLine(text,len)) + { code=false; + shader_data->code=code_parse.start; + shader_data->code_length=code_parse.end-code_parse.start; + } + return(true); } @@ -252,7 +283,7 @@ namespace UniformAttrib ua; if(ParseUniformAttrib(&ua,text)) - output_list.Add(ua); + shader_data->output.Add(ua); } if(hgl::stricmp(text,"Code",4)==0) @@ -271,13 +302,16 @@ namespace struct GeometryShaderBlockParse:public ShaderBlockParse { - Prim input_prim; - Prim output_prim; - uint max_vertices; + GeometryShaderData *gsd=nullptr; 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) return(false); @@ -297,7 +331,7 @@ namespace if(!CheckGeometryShaderIn(ip)) return(false); - input_prim=ip; + gsd->input_prim=ip; return(true); } else @@ -316,15 +350,15 @@ namespace if(!CheckGeometryShaderOut(op)) return(false); - output_prim=op; + gsd->output_prim=op; while(*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(true); @@ -338,26 +372,30 @@ namespace };//struct GeometryShaderBlockParse - struct MaterialFileParse:public TextParse + struct MaterialTextParse:public MaterialFileParse { MaterialFileBlock state; - TextParse *parse; + MaterialFileParse *parse; + + MaterialFileData *mfd; public: - MaterialFileParse() + MaterialTextParse(MaterialFileData *fd) { state=MaterialFileBlock::None; parse=nullptr; + + mfd=fd; } - ~MaterialFileParse() + ~MaterialTextParse() { 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) return(false); @@ -368,16 +406,50 @@ namespace 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; - 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; + ShaderData *sd=nullptr; - 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); @@ -391,35 +463,30 @@ namespace }; }//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_os_filename=filesystem::MergeFilename(OS_TEXT("ShaderLibrary"),mtl_osfn); if(!filesystem::FileExist(mtl_os_filename)) - return(false); + return nullptr; - io::OpenFileInputStream fis(mtl_os_filename); + char *data; //未来二进制版本的材质文件,也是使用LoadFileToMemory加载。这里为了统一,所以文本也这么操作。 - if(!fis) - return(false); + int size=filesystem::LoadFileToMemory(mtl_os_filename,(void **)&data,true); - MaterialFileParse mtp; + MaterialFileData *mfd=new MaterialFileData(data,size); - io::TextInputStream tis(fis,0); + MaterialTextParse mtp(mfd); + + io::TextInputStream tis(data,size); tis.SetParseCallback(&mtp); - return tis.Run(); -} + if(!tis.Run()) + return nullptr; -MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const MaterialCreateConfig *cfg) -{ - return nullptr; + return mfd; } - -//MaterialCreateInfo *LoadMaterialFromFile(const AnsiString &name,const Material3DCreateConfig *cfg) -//{ -//} STD_MTL_NAMESPACE_END