From d4b58f0e6bec9f02dc1a8b20f6fde99c56d52aa9 Mon Sep 17 00:00:00 2001 From: ducphamhong Date: Wed, 15 Jan 2020 21:38:36 +0700 Subject: [PATCH] featL #47 load extra material data --- .../Engine/Source/Material/CMaterial.cpp | 97 ++++++++++++++++--- .../Engine/Source/Material/CMaterial.h | 14 ++- .../Source/Material/CMaterialManager.cpp | 52 +++++++--- 3 files changed, 134 insertions(+), 29 deletions(-) diff --git a/Projects/Skylicht/Engine/Source/Material/CMaterial.cpp b/Projects/Skylicht/Engine/Source/Material/CMaterial.cpp index 61f04e023..dd4ce18be 100644 --- a/Projects/Skylicht/Engine/Source/Material/CMaterial.cpp +++ b/Projects/Skylicht/Engine/Source/Material/CMaterial.cpp @@ -258,12 +258,36 @@ namespace Skylicht } } + CMaterial::SExtraParams *CMaterial::newExtra(const char *shaderPath) + { + SExtraParams *e = new SExtraParams(); + e->ShaderPath = shaderPath; + m_extras.push_back(e); + return e; + } + + void CMaterial::setExtraUniformTexture(SExtraParams *e, const char *name, const char *path) + { + SUniformTexture *t = getExtraUniformTexture(e, name); + t->Path = path; + } + + void CMaterial::setExtraUniform(SExtraParams *e, const char *name, float *f, int floatSize) + { + SUniformValue *t = getExtraUniform(e, name); + t->FloatSize = floatSize; + t->FloatValue[0] = f[0]; + t->FloatValue[1] = f[1]; + t->FloatValue[2] = f[2]; + t->FloatValue[3] = f[3]; + } + CMaterial::SUniformValue* CMaterial::getUniform(const char *name) { - for (int i = 0, n = (int)m_uniformParams.size(); i < n; i++) + for (SUniformValue *uniform : m_uniformParams) { - if (m_uniformParams[i]->Name == name) - return m_uniformParams[i]; + if (uniform->Name == name) + return uniform; } return newUniform(name, 4); @@ -271,9 +295,9 @@ namespace Skylicht bool CMaterial::haveUniform(const char *name) { - for (int i = 0, n = (int)m_uniformParams.size(); i < n; i++) + for (SUniformValue *uniform : m_uniformParams) { - if (m_uniformParams[i]->Name == name) + if (uniform->Name == name) return true; } @@ -282,15 +306,37 @@ namespace Skylicht CMaterial::SUniformTexture* CMaterial::getUniformTexture(const char *name) { - for (int i = 0, n = (int)m_uniformTextures.size(); i < n; i++) + for (SUniformTexture *uniform : m_uniformTextures) { - if (m_uniformTextures[i]->Name == name) - return m_uniformTextures[i]; + if (uniform->Name == name) + return uniform; } return newUniformTexture(name); } + CMaterial::SUniformValue* CMaterial::getExtraUniform(SExtraParams *e, const char *name) + { + for (SUniformValue *uniform : e->UniformParams) + { + if (uniform->Name == name) + return uniform; + } + + return newExtraUniform(e, name, 4); + } + + CMaterial::SUniformTexture* CMaterial::getExtraUniformTexture(SExtraParams *e, const char *name) + { + for (SUniformTexture *uniform : e->UniformTextures) + { + if (uniform->Name == name) + return uniform; + } + + return newExtraUniformTexture(e, name); + } + void CMaterial::setProperty(const std::string& name, const std::string& value) { bool booleanValue = false; @@ -663,6 +709,25 @@ namespace Skylicht return p; } + CMaterial::SUniformTexture *CMaterial::newExtraUniformTexture(SExtraParams *e, const char *name) + { + SUniformTexture *p = new SUniformTexture(); + p->Name = name; + + e->UniformTextures.push_back(p); + return p; + } + + CMaterial::SUniformValue *CMaterial::newExtraUniform(SExtraParams *e, const char *name, int floatSize) + { + SUniformValue *p = new SUniformValue(); + p->Name = name; + p->FloatSize = floatSize; + + e->UniformParams.push_back(p); + return p; + } + void CMaterial::updateTexture(SMaterial& mat) { CShaderManager *shaderManager = CShaderManager::getInstance(); @@ -713,7 +778,7 @@ namespace Skylicht CShader* shader = shaderManager->getShaderByPath(m_shaderPath.c_str()); if (shader != NULL) { - mat.MaterialType = shaderManager->getShaderIDByName(shader->getName().c_str()); + mat.MaterialType = shader->getMaterialRenderID(); // manual init if (m_manualInitMaterial == true) @@ -880,9 +945,7 @@ namespace Skylicht SExtraParams *e = getExtraParams(m_shaderPath.c_str()); if (e == NULL) { - e = new SExtraParams(); - e->ShaderPath = m_shaderPath; - m_extras.push_back(e); + e = newExtra(m_shaderPath.c_str()); } // clear old params @@ -981,8 +1044,14 @@ namespace Skylicht { for (CMaterial::SUniformTexture *t : e->UniformTextures) { - if (t->Name == name && t->Texture != NULL) - return t; + if (t->Name == name) + { + if (t->Texture == NULL) + t->Texture = CTextureManager::getInstance()->getTexture(t->Path.c_str()); + + if (t->Texture != NULL) + return t; + } } } diff --git a/Projects/Skylicht/Engine/Source/Material/CMaterial.h b/Projects/Skylicht/Engine/Source/Material/CMaterial.h index 923de696f..5738fb676 100644 --- a/Projects/Skylicht/Engine/Source/Material/CMaterial.h +++ b/Projects/Skylicht/Engine/Source/Material/CMaterial.h @@ -136,7 +136,7 @@ namespace Skylicht } CMaterial* clone(CGameObject *gameObject); - + void deleteAllParams(); void deleteExtramParams(); @@ -150,6 +150,10 @@ namespace Skylicht void setUniformTexture(const char *name, const char *path, std::vector& folder, bool loadTexture = true); void setUniformTexture(const char *name, ITexture *texture); + SExtraParams *newExtra(const char *shaderPath); + void setExtraUniformTexture(SExtraParams *e, const char *name, const char *path); + void setExtraUniform(SExtraParams *e, const char *name, float *f, int floatSize); + inline std::vector& getUniformParams() { return m_uniformParams; @@ -169,6 +173,10 @@ namespace Skylicht SUniformTexture* getUniformTexture(const char *name); + SUniformValue* getExtraUniform(SExtraParams *e, const char *name); + + SUniformTexture* getExtraUniformTexture(SExtraParams *e, const char *name); + bool haveUniform(const char *name); void initMaterial(); @@ -222,6 +230,10 @@ namespace Skylicht SUniformTexture *newUniformTexture(const char *name); + SUniformTexture *newExtraUniformTexture(SExtraParams *e, const char *name); + + SUniformValue *newExtraUniform(SExtraParams *e, const char *name, int floatSize); + void addShaderUI(CShader::SUniformUI* ui); SExtraParams* getExtraParams(const char *shaderPath); diff --git a/Projects/Skylicht/Engine/Source/Material/CMaterialManager.cpp b/Projects/Skylicht/Engine/Source/Material/CMaterialManager.cpp index 9572e42df..4a5fc35c5 100644 --- a/Projects/Skylicht/Engine/Source/Material/CMaterialManager.cpp +++ b/Projects/Skylicht/Engine/Source/Material/CMaterialManager.cpp @@ -79,6 +79,8 @@ namespace Skylicht CMaterial *material = NULL; + CMaterial::SExtraParams *extra = NULL; + while (xmlRead->read()) { switch (xmlRead->getNodeType()) @@ -98,12 +100,19 @@ namespace Skylicht // create material material = new CMaterial(name.c_str(), shader.c_str()); + extra = NULL; if (loadTexture == true) material->loadDefaultTexture(); result.push_back(material); } + if (nodeName == L"Extra") + { + textw = xmlRead->getAttributeValue(L"name"); + CStringImp::convertUnicodeToUTF8(textw, text); + extra = material->newExtra(text); + } else if (nodeName == L"Property") { if (material != NULL) @@ -135,7 +144,12 @@ namespace Skylicht CStringImp::convertUnicodeToUTF8(textw, text); std::string name = text; if (path.empty() == false) - material->setUniformTexture(name.c_str(), path.c_str(), textureFolders, loadTexture); + { + if (extra == NULL) + material->setUniformTexture(name.c_str(), path.c_str(), textureFolders, loadTexture); + else + material->setExtraUniformTexture(extra, name.c_str(), path.c_str()); + } } // load texture by uniform slot @@ -146,7 +160,10 @@ namespace Skylicht int slot = atoi(text); const char *name = material->getUniformTextureName(slot); if (name != NULL) - material->setUniformTexture(name, path.c_str(), textureFolders, loadTexture); + { + if (extra == NULL) + material->setUniformTexture(name, path.c_str(), textureFolders, loadTexture); + } } } } @@ -168,14 +185,21 @@ namespace Skylicht sscanf(text, "%f,%f,%f,%f", &v[0], &v[1], &v[2], &v[3]); // set uniform param - if (floatSize == 1) - material->setUniform(name.c_str(), v[0]); - else if (floatSize == 2) - material->setUniform2(name.c_str(), v); - else if (floatSize == 3) - material->setUniform3(name.c_str(), v); - else if (floatSize == 4) - material->setUniform4(name.c_str(), v); + if (extra == NULL) + { + if (floatSize == 1) + material->setUniform(name.c_str(), v[0]); + else if (floatSize == 2) + material->setUniform2(name.c_str(), v); + else if (floatSize == 3) + material->setUniform3(name.c_str(), v); + else if (floatSize == 4) + material->setUniform4(name.c_str(), v); + } + else + { + material->setExtraUniform(extra, name.c_str(), v, floatSize); + } } } } @@ -264,19 +288,19 @@ namespace Skylicht if (e->UniformTextures.size() > 0) { // write uniform texture - buffer += "\t\t\t\t\n"; + buffer += "\t\t\t\t\n"; for (CMaterial::SUniformTexture* texture : e->UniformTextures) { - sprintf(data, "\t\t\t\t\t\n", texture->Name.c_str(), texture->Path.c_str()); + sprintf(data, "\t\t\t\t\t\n", texture->Name.c_str(), texture->Path.c_str()); buffer += data; } - buffer += "\t\t\t\t\n"; + buffer += "\t\t\t\t\n"; } if (e->UniformParams.size() > 0) { // write uniform value - buffer += "\t\t\t\t\n"; + buffer += "\t\t\t\t\n"; for (CMaterial::SUniformValue* param : e->UniformParams) { sprintf(data, "\t\t\t\t\t\n",