Commit da3e0459 authored by admin@ds-servers.com's avatar admin@ds-servers.com

New material system (continue)

parent 2ddbaa39
Subproject commit e3b3ec5efda5427067501b177f34866affd2ce65
Subproject commit 04794d7047ef1af9f1cb4799828689fd8d60e9ed
......@@ -48,6 +48,7 @@ struct XSHADER_VARIANT_DESC
struct XVertexOutputElement
{
//! Имя переменной
const char *szName;
//! Тип
......@@ -58,7 +59,50 @@ struct XVertexOutputElement
};
#define XVERTEX_OUTPUT_DECL_END() {NULL,GXDECLTYPE_UNUSED,(GXDECLUSAGE)0}
struct XRenderPassTexturesElement
{
//! Имя текстуры
const char *szName;
//! Имя переменной
const char *szKey;
//! Слот в шейдере
UINT uSlot;
};
#define XRENDER_PASS_TEXTURES_LIST_END() {NULL,NULL,~0u}
struct XRenderPassSamplersElement
{
//! Имя семплера
const char *szName;
//! Имя переменной
const char *szKey;
//! Слот в шейдере
UINT uSlot;
};
#define XRENDER_PASS_SAMPLERS_LIST_END() {NULL,NULL,~0u}
struct XRenderPassOutputElement
{
//! Имя выхода
const char *szName;
//! Имя переменной
const char *szKey;
//! Тип
GXDECLTYPE type;
//! Значение по умолчанию (hlsl)
const char *szDefault;
};
#define XRENDER_PASS_OUTPUT_LIST_END() {NULL,NULL,GXDECLTYPE_UNUSED,NULL}
struct XVertexFormatHandler {};
struct XRenderPassHandler {};
struct XVertexShaderHandler {};
struct XGeometryShaderHandler {};
......@@ -112,6 +156,12 @@ public:
virtual XGeometryShaderHandler* XMETHODCALLTYPE registerGeometryShader(const char *szShaderFile, const char **aszRequiredParameters, GXMacro *pDefines = NULL) = 0;
virtual void XMETHODCALLTYPE bindGS(XGeometryShaderHandler *pGeometryShader) = 0;
// ["GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0],
// ["Scene default", "g_sScene", 0]
// ["Base color", "vBaseColor", 'GXDECLTYPE_FLOAT4', "float4(1.0f, 0.0f, 0.0f, 0.5f)"],
virtual XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput) = 0;
virtual XRenderPassHandler* XMETHODCALLTYPE getRenderPass(const char *szName) = 0;
};
#endif
......@@ -301,7 +301,6 @@ XVertexShaderHandler* XMETHODCALLTYPE CMaterialSystem::registerVertexShader(XVer
return(vsData);
}
void XMETHODCALLTYPE CMaterialSystem::bindVS(XVertexShaderHandler *pVertexShader)
{
m_pCurrentVS = (VertexShaderData*)pVertexShader;
......@@ -311,13 +310,13 @@ XGeometryShaderHandler* XMETHODCALLTYPE CMaterialSystem::registerGeometryShader(
{
assert(szShaderFile);
GeometryShaderData *gsData = m_poolGSdata.Alloc();
GeometryShader *gsData = m_poolGSdata.Alloc();
//vsData->idShader = SGCore_ShaderLoad(SHADER_TYPE_VERTEX, szShaderFile, NULL, pDefines);
gsData->szShaderFile = strdup(szShaderFile);
while(aszRequiredParameters)
while(aszRequiredParameters && *aszRequiredParameters)
{
gsData->aszRequiredParameters.push_back(*aszRequiredParameters);
gsData->aszRequiredParameters.push_back(strdup(*aszRequiredParameters));
++aszRequiredParameters;
}
......@@ -330,16 +329,77 @@ XGeometryShaderHandler* XMETHODCALLTYPE CMaterialSystem::registerGeometryShader(
++pDefines;
}
m_aGeometryShaders.push_back(gsData);
updateReferences();
return(gsData);
}
void XMETHODCALLTYPE CMaterialSystem::bindGS(XGeometryShaderHandler *pGeometryShader)
{
m_pCurrentGS = (GeometryShaderData*)pGeometryShader;
m_pCurrentGS = (GeometryShader*)pGeometryShader;
}
XRenderPassHandler* XMETHODCALLTYPE CMaterialSystem::registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput)
{
if(m_mRenderPasses.KeyExists(szName))
{
LibReport(REPORT_MSG_LEVEL_ERROR, "CMaterialSystem::registerRenderPass(): pass '%s' already been registered!\n", szName);
return(NULL);
}
RenderPass &pass = m_mRenderPasses[szName];
pass.szName = strdup(szName);
pass.szShaderFile = strdup(szShaderFile);
while(pTextures && pTextures->szName)
{
XRenderPassTexturesElement tmp = *pTextures;
tmp.szKey = strdup(tmp.szKey);
tmp.szName = strdup(tmp.szName);
pass.aTextures.push_back(tmp);
++pTextures;
}
while(pSamplers && pSamplers->szName)
{
XRenderPassSamplersElement tmp = *pSamplers;
tmp.szKey = strdup(tmp.szKey);
tmp.szName = strdup(tmp.szName);
pass.aSamplers.push_back(tmp);
++pSamplers;
}
while(pOutput && pOutput->szName)
{
XRenderPassOutputElement tmp = *pOutput;
tmp.szKey = strdup(tmp.szKey);
tmp.szName = strdup(tmp.szName);
tmp.szDefault = strdup(tmp.szDefault);
pass.aOutput.push_back(tmp);
++pOutput;
}
updateReferences();
return(&pass);
}
XRenderPassHandler* XMETHODCALLTYPE CMaterialSystem::getRenderPass(const char *szName)
{
const AssotiativeArray<String, RenderPass>::Node *pNode;
if(m_mRenderPasses.KeyExists(szName, &pNode))
{
return(pNode->Val);
}
return(NULL);
}
void CMaterialSystem::updateReferences()
{
for(AssotiativeArray<String, VertexFormatData>::Iterator i = m_mVertexFormats.begin(); i; i++)
......@@ -347,73 +407,63 @@ void CMaterialSystem::updateReferences()
VertexFormatData *pFormat = i.second;
for(UINT j = 0, jl = m_aGeometryShaders.size(); j < jl; ++j)
{
GeometryShaderData *pGS = m_aGeometryShaders[j];
GeometryShader *pGS = m_aGeometryShaders[j];
if(pFormat->aGS.size() <= j || !pFormat->aGS[j])
{
/*
$iFound = 0;
$aPassParameters = [];
foreach($data['decl'] as $decl)
int iFound = 0;
Array<XVertexOutputElement*> aPassParameters;
for(UINT k = 0, kl = pFormat->aDecl.size(); k < kl; ++k)
{
if(in_array($decl['key'], $requiredParameters))
XVertexOutputElement *pEl = &pFormat->aDecl[k];
if(pGS->aszRequiredParameters.indexOf(pEl->szName, [](const char *a, const char *b){
return(!fstrcmp(a, b));
}) >= 0)
{
// echo("using: {$decl['key']}\n");
++$iFound;
++iFound;
}
else
else
{
// echo("passing: {$decl['key']}\n");
$aPassParameters[] = $decl;
aPassParameters.push_back(pEl);
}
}
if($iFound + count($aPassParameters) != count($data['decl']))
{
// var_dump($iFound, count($aPassParameters), count($data['decl']));
echo("Cannot use shader {$sFile} with {$sFormat} format. Skipping.\n");
$data['GS'][$key] = null;
}
else
GeometryShaderData *gsData = m_aGeometryShadersData.Alloc();
pFormat->aGS[j] = gsData;
if(iFound != (int)pGS->aszRequiredParameters.size())
{
// print_r($aPassParameters);
gsData->isSkipped = true;
LibReport(REPORT_MSG_LEVEL_WARNING, "Cannot use shader '%s' with '%s' format. Skipping.\n", pGS->szShaderFile, i.first->c_str());
continue;
}
$defines = [];
$aStruct = [];
$aPass = [];
foreach($aPassParameters as $decl)
gsData->isSkipped = false;
gsData->aDefines = pGS->aDefines;
gsData->iCommonDefines = gsData->aDefines.size();
String sPass, sStruct;
for(UINT k = 0, kl = aPassParameters.size(); k < kl; ++k)
{
$aStruct[] = $this->getHLSLType($decl['type'])." {$decl['key']}: ".$this->getHLSLSemantic($decl['usage']);
$aPass[] = "(dst).{$decl['key']} = (src).{$decl['key']}";
XVertexOutputElement *el = aPassParameters[k];
if(k != 0)
{
sStruct += "; ";
sPass += "; ";
}
sStruct += String(getHLSLType(el->type)) + " " + el->szName + ": " + getHLSLSemantic(el->usage);
sPass += String("(dst).") + el->szName + " = (src)." + el->szName;
}
$defines['XMAT_GS_STRUCT()'] = implode('; ', $aStruct);
$defines['XMAT_GS_PASS(dst, src)'] = implode('; ', $aPass);
$data['GS'][$key] = [
'file' => $sFile,
'defines' => array_merge($aDefines, $defines),
'isCompiled' => false,
];
*/
gsData->aDefines.push_back({"XMAT_GS_STRUCT()", strdup(sStruct.c_str())});
gsData->aDefines.push_back({"XMAT_GS_PASS(dst, src)", strdup(sPass.c_str())});
gsData->aDefines.push_back({NULL, NULL});
gsData->idShader = SGCore_ShaderLoad(SHADER_TYPE_GEOMETRY, pGS->szShaderFile, NULL, &gsData->aDefines[0]);
}
}
}
/*
foreach($this->m_aGeometryShaders as $key => &$aGS)
{
$sFile = $aGS['file'];
$requiredParameters = $aGS['params'];
$aDefines = $aGS['defines'];
foreach($this->m_aVertexFormats as $sFormat => &$data)
{
if(!isset($data['GS'][$key]))
{
}
}
}
*/
}
void CMaterialSystem::cleanData()
......@@ -435,6 +485,17 @@ void CMaterialSystem::cleanData()
m_poolVSdata.Delete(i.second->aVS[j]);
}
for(UINT j = 0, jl = i.second->aGS.size(); j < jl; ++j)
{
for(UINT k = i.second->aGS[j]->iCommonDefines, kl = i.second->aGS[j]->aDefines.size(); k < kl; ++k)
{
free((void*)i.second->aGS[j]->aDefines[k].szDefinition);
//free((void*)i.second->aGS[j]->aDefines[k].szName);
}
m_aGeometryShadersData.Delete(i.second->aGS[j]);
}
}
for(UINT i = 0, l = m_aGeometryShaders.size(); i < l; ++i)
......@@ -452,6 +513,32 @@ void CMaterialSystem::cleanData()
m_poolGSdata.Delete(m_aGeometryShaders[i]);
}
for(AssotiativeArray<String, RenderPass>::Iterator i = m_mRenderPasses.begin(); i; i++)
{
RenderPass *pPass = i.second;
free((void*)pPass->szName);
free((void*)pPass->szShaderFile);
for(UINT j = 0, jl = pPass->aTextures.size(); j < jl; ++j)
{
free((void*)pPass->aTextures[j].szName);
free((void*)pPass->aTextures[j].szKey);
}
for(UINT j = 0, jl = pPass->aSamplers.size(); j < jl; ++j)
{
free((void*)pPass->aSamplers[j].szName);
free((void*)pPass->aSamplers[j].szKey);
}
for(UINT j = 0, jl = pPass->aOutput.size(); j < jl; ++j)
{
free((void*)pPass->aOutput[j].szName);
free((void*)pPass->aOutput[j].szKey);
free((void*)pPass->aOutput[j].szDefault);
}
}
}
//#############################################################################
......
......@@ -101,6 +101,9 @@ public:
XGeometryShaderHandler* XMETHODCALLTYPE registerGeometryShader(const char *szShaderFile, const char **aszRequiredParameters, GXMacro *pDefines = NULL) override;
void XMETHODCALLTYPE bindGS(XGeometryShaderHandler *pGeometryShader) override;
XRenderPassHandler* XMETHODCALLTYPE registerRenderPass(const char *szName, const char *szShaderFile, XRenderPassTexturesElement *pTextures, XRenderPassSamplersElement *pSamplers, XRenderPassOutputElement *pOutput) override;
XRenderPassHandler* XMETHODCALLTYPE getRenderPass(const char *szName) override;
void queueTextureUpload(CTexture *pTexture);
void onTextureRelease(CTexture *pTexture);
void update(float fDT);
......@@ -129,14 +132,20 @@ protected:
VertexFormatData *pVertexFormat;
Array<GXMacro> aDefines; //!< @fixme: нужно ли это хранить?
};
struct GeometryShaderData: public XGeometryShaderHandler
struct GeometryShader: public XGeometryShaderHandler
{
const char *szShaderFile;
//ID idShader;
//VertexFormatData *pVertexFormat;
Array<GXMacro> aDefines;
Array<const char*> aszRequiredParameters;
};
struct GeometryShaderData
{
bool isSkipped;
Array<GXMacro> aDefines;
int iCommonDefines;
ID idShader;
};
struct VertexFormatData: public XVertexFormatHandler
{
......@@ -145,13 +154,99 @@ protected:
Array<GeometryShaderData*> aGS;
};
struct RenderPass: public XRenderPassHandler
{
const char *szName;
const char *szShaderFile;
Array<XRenderPassTexturesElement> aTextures;
Array<XRenderPassSamplersElement> aSamplers;
Array<XRenderPassOutputElement> aOutput;
};
AssotiativeArray<String, VertexFormatData> m_mVertexFormats;
MemAlloc<VertexShaderData> m_poolVSdata;
MemAlloc<GeometryShaderData> m_poolGSdata;
Array<GeometryShaderData*> m_aGeometryShaders;
MemAlloc<GeometryShader> m_poolGSdata;
Array<GeometryShader*> m_aGeometryShaders;
MemAlloc<GeometryShaderData> m_aGeometryShadersData;
AssotiativeArray<String, RenderPass> m_mRenderPasses;
VertexShaderData *m_pCurrentVS = NULL;
GeometryShaderData *m_pCurrentGS = NULL;
GeometryShader *m_pCurrentGS = NULL;
const char* getHLSLType(GXDECLTYPE type)
{
switch(type)
{
case GXDECLTYPE_FLOAT1:
return("float");
case GXDECLTYPE_FLOAT2:
return("float2");
case GXDECLTYPE_FLOAT3:
return("float3");
case GXDECLTYPE_FLOAT4:
return("float4");
}
assert(!"Unknown type");
return("");
}
int getTypeSize(GXDECLTYPE type)
{
switch(type)
{
case GXDECLTYPE_FLOAT1:
return(1);
case GXDECLTYPE_FLOAT2:
return(2);
case GXDECLTYPE_FLOAT3:
return(3);
case GXDECLTYPE_FLOAT4:
return(4);
}
assert(!"Unknown type");
return(0);
}
const char* getHLSLSemantic(GXDECLUSAGE usage)
{
switch(usage)
{
case GXDECLUSAGE_POSITION:
return("POSITION0");
case GXDECLUSAGE_TEXCOORD:
return("TEXCOORD0");
case GXDECLUSAGE_TEXCOORD1:
return("TEXCOORD1");
case GXDECLUSAGE_TEXCOORD2:
return("TEXCOORD2");
case GXDECLUSAGE_TEXCOORD3:
return("TEXCOORD3");
case GXDECLUSAGE_TEXCOORD4:
return("TEXCOORD4");
case GXDECLUSAGE_TEXCOORD5:
return("TEXCOORD5");
case GXDECLUSAGE_TEXCOORD6:
return("TEXCOORD6");
case GXDECLUSAGE_TEXCOORD7:
return("TEXCOORD7");
case GXDECLUSAGE_BINORMAL:
return("BINORMAL0");
case GXDECLUSAGE_BLENDINDICES:
return("BLENDINDICES0");
case GXDECLUSAGE_BLENDWEIGHT:
return("BLENDWEIGHT0");
case GXDECLUSAGE_COLOR:
return("COLOR0");
case GXDECLUSAGE_NORMAL:
return("NORMAL0");
case GXDECLUSAGE_TANGENT:
return("TANGENT0");
case GXDECLUSAGE_TESSFACTOR:
return("TESSFACTOR0");
}
assert(!"Unknown usage");
return("");
}
};
#endif
......@@ -44,10 +44,136 @@ CRenderPipeline::CRenderPipeline(IGXDevice *pDevice):
"vPos",
NULL
};
XGeometryShaderHandler *pRSMGeometryShader = m_pMaterialSystem->registerGeometryShader("sm/rsm_cube.gs", aszGSRequiredParams);
XGeometryShaderHandler *pRSMGeometryShader = m_pMaterialSystem->registerGeometryShader("sm/rsmcube.gs", aszGSRequiredParams);
m_pMaterialSystem->registerVertexShader(pVertexFormatPostprocess, "base/post.vs");
{
XRenderPassSamplersElement pSamplers[] = {
{"Scene default", "g_sScene", 0},
XRENDER_PASS_SAMPLERS_LIST_END()
};
XRenderPassOutputElement pOutput[] = {
{"Base color", "vBaseColor", GXDECLTYPE_FLOAT3, "float3(1.0f, 0.0f, 0.0f)"},
{"Normal", "vNormal", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
{"AO", "fAO", GXDECLTYPE_FLOAT1, "0.0f"},
{"f0", "f0", GXDECLTYPE_FLOAT1, "0.04f"},
{"Roughness", "fRoughness", GXDECLTYPE_FLOAT1, "0.5f"},
{"Metallic", "fMetallic", GXDECLTYPE_FLOAT1, "0.5f"},
{"Thickness", "fThickness", GXDECLTYPE_FLOAT1, "1.0f"},
{"Lighting Coefficient", "fLightCoeff", GXDECLTYPE_FLOAT1, "1.0f"},
{"Height", "fHeight", GXDECLTYPE_FLOAT1, "1.0f"},
XRENDER_PASS_OUTPUT_LIST_END()
};
m_pMaterialSystem->registerRenderPass("xGBuffer", "shaders/material/gbuffer.ps", NULL, pSamplers, pOutput);
}
{
XRenderPassTexturesElement pTextures[] = {
{"GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0},
{"GBuffer normals(rgb) f0(a)", "g_txGBufferN3F1", 1},
{"GBuffer depth(r)", "g_txGBufferD1", 2},
{"", "", 3}, // reserved slot
// {"GBuffer roughness(r) metallic(g) thickness(b) AO(a)", "g_txGBufferR1M1T1AO1", 3},
{"Lighted scene", "g_txScene", 4},
XRENDER_PASS_TEXTURES_LIST_END()
};
XRenderPassSamplersElement pSamplers[] = {
{"Scene default", "g_sScene", 0},
{"Point clamp", "g_sPointClamp", 1},
XRENDER_PASS_SAMPLERS_LIST_END()
};
XRenderPassOutputElement pOutput[] = {
{"Base color", "vBaseColor", GXDECLTYPE_FLOAT4, "float4(1.0f, 0.0f, 0.0f, 0.5f)"},
{"Normal", "vNormal", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
{"AO", "fAO", GXDECLTYPE_FLOAT1, "0.0f"},
{"f0", "f0", GXDECLTYPE_FLOAT1, "0.04f"},
{"Roughness", "fRoughness", GXDECLTYPE_FLOAT1, "0.5f"},
{"Metallic", "fMetallic", GXDECLTYPE_FLOAT1, "0.5f"},
{"Thickness", "fThickness", GXDECLTYPE_FLOAT1, "1.0f"},
{"Lighting Coefficient", "fLightCoeff", GXDECLTYPE_FLOAT1, "1.0f"},
{"Emissive color", "fEmissiveColor", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
XRENDER_PASS_OUTPUT_LIST_END()
};
m_pMaterialSystem->registerRenderPass("xTransparency", "shaders/material/transparent.ps", pTextures, pSamplers, pOutput);
}
{
XRenderPassTexturesElement pTextures[] = {
{"GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0},
{"GBuffer normals(rgb) f0(a)", "g_txGBufferN3F1", 1},
{"GBuffer depth(r)", "g_txGBufferD1", 2},
{"", "", 3}, // reserved slot
// {"GBuffer roughness(r) metallic(g) thickness(b) AO(a)", "g_txGBufferR1M1T1AO1", 3},
{"Lighted scene", "g_txScene", 4},
XRENDER_PASS_TEXTURES_LIST_END()
};
XRenderPassSamplersElement pSamplers[] = {
{"Scene default", "g_sScene", 0},
{"Point clamp", "g_sPointClamp", 1},
XRENDER_PASS_SAMPLERS_LIST_END()
};
XRenderPassOutputElement pOutput[] = {
{"Emissive color", "fEmissiveColor", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
{"Normal", "vNormal", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
XRENDER_PASS_OUTPUT_LIST_END()
};
m_pMaterialSystem->registerRenderPass("xIllumination", "shaders/material/illum.ps", pTextures, pSamplers, pOutput);
}
{
XRenderPassTexturesElement pTextures[] = {
{"GBuffer color(rgb) light(a)", "g_txGBufferC3L1", 0},
{"GBuffer normals(rgb) f0(a)", "g_txGBufferN3F1", 1},
{"GBuffer depth(r)", "g_txGBufferD1", 2},
{"", "", 3}, // reserved slot
// {"GBuffer roughness(r) metallic(g) thickness(b) AO(a)", "g_txGBufferR1M1T1AO1", 3},
{"Lighted scene", "g_txScene", 4},
XRENDER_PASS_TEXTURES_LIST_END()
};
XRenderPassSamplersElement pSamplers[] = {
{"Scene default", "g_sScene", 0},
{"Point clamp", "g_sPointClamp", 1},
XRENDER_PASS_SAMPLERS_LIST_END()
};
XRenderPassOutputElement pOutput[] = {
{"Color", "vColor", GXDECLTYPE_FLOAT3, "float3(1.0f, 0.0f, 0.0f)"},
XRENDER_PASS_OUTPUT_LIST_END()
};
m_pMaterialSystem->registerRenderPass("xPostprocess", "shaders/material/post.ps", pTextures, pSamplers, pOutput);
}
{
XRenderPassSamplersElement pSamplers[] = {
{"Scene default", "g_sScene", 0},
// {"Point clamp", "g_sPointClamp", 1},
XRENDER_PASS_SAMPLERS_LIST_END()
};
XRenderPassOutputElement pOutput[] = {
{"Base color", "vBaseColor", GXDECLTYPE_FLOAT3, "float3(1.0f, 0.0f, 0.0f)"},
{"Normal", "vNormal", GXDECLTYPE_FLOAT3, "float3(0.0f, 0.0f, 0.0f)"},
XRENDER_PASS_OUTPUT_LIST_END()
};
m_pMaterialSystem->registerRenderPass("xShadow", "shaders/material/shadow.ps", NULL, pSamplers, pOutput);
}
IXRenderable *pRenderable;
UINT ic = 0;
while((pRenderable = (IXRenderable*)pPluginManager->getInterface(IXRENDERABLE_GUID, ic++)))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment