Skip to content

Commit

Permalink
feat: #47 Add change shader function on material
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed Jan 15, 2020
1 parent dbd58c0 commit b489da9
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 19 deletions.
224 changes: 219 additions & 5 deletions Projects/Skylicht/Engine/Source/Material/CMaterial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace Skylicht
m_textures[i] = NULL;
}

for (int i = 0; i < CShader::RResourceCount; i++)
for (int i = 0; i < CShader::ResourceCount; i++)
m_overrideTextures[i] = NULL;

initMaterial();
Expand All @@ -68,6 +68,7 @@ namespace Skylicht
}

deleteAllParams();
deleteExtramParams();
clearAllAffectMesh();
}

Expand Down Expand Up @@ -118,6 +119,24 @@ namespace Skylicht
m_uniformTextures.clear();
}

void CMaterial::deleteExtramParams()
{
for (SExtraParams *&e : m_extras)
{
for (SUniformValue *&uniform : e->UniformParams)
delete uniform;
e->UniformParams.clear();

for (SUniformTexture *&uniform : e->UniformTextures)
delete uniform;
e->UniformTextures.clear();

delete e;
}

m_extras.clear();
}

void CMaterial::setUniform(const char *name, float f)
{
SUniformValue* p = getUniform(name);
Expand Down Expand Up @@ -392,19 +411,19 @@ namespace Skylicht
}
else
{
if (r->Type == CShader::RTexture)
if (r->Type == CShader::Texture)
{
texture = textureManager->getTexture(r->Path.c_str());
}
else if (r->Type == CShader::RCubeTexture)
else if (r->Type == CShader::CubeTexture)
{

}
else if (r->Type == CShader::RStaticCubeTexture)
else if (r->Type == CShader::StaticCubeTexture)
{

}
else if (r->Type == CShader::RShadowMapTexture)
else if (r->Type == CShader::ShadowMapTexture)
{

}
Expand Down Expand Up @@ -488,6 +507,8 @@ namespace Skylicht
}
}

// PUBLIC FOR USE

void CMaterial::applyMaterial(SMaterial& mat)
{
loadDefaultTexture();
Expand Down Expand Up @@ -517,6 +538,59 @@ namespace Skylicht
}
}

void CMaterial::changeShader(CShader *shader)
{
// save current shader params
saveExtraParams();

// new shader path
m_shaderPath = shader->getShaderPath();

// init default params
initMaterial();

// try load from extra params
reloadExtraParams(m_shaderPath.c_str());
}

void CMaterial::changeShader(const char *path)
{
CShaderManager *shaderManager = CShaderManager::getInstance();
CShader* shader = shaderManager->getShaderByPath(path);
if (shader != NULL)
{
changeShader(shader);
}
else
{
// try load shader
CShader *shader = shaderManager->loadShader(path);
if (shader != NULL)
{
changeShader(shader);
}
}
}

void CMaterial::autoDetectLoadTexture()
{
CShaderManager *shaderManager = CShaderManager::getInstance();
CShader* shader = shaderManager->getShaderByPath(m_shaderPath.c_str());
if (shader != NULL)
{
for (SUniformTexture *texture : m_uniformTextures)
{
CShader::SUniformUI* ui = shader->getUniformUIByName(texture->Name.c_str());

// need try to fill and load texture
if (ui != NULL && texture->Texture == NULL)
{

}
}
}
}

// PRIVATE & PROTECTED

void CMaterial::initDefaultValue()
Expand Down Expand Up @@ -788,4 +862,144 @@ namespace Skylicht

v->ShaderDefaultValue = true;
}

CMaterial::SExtraParams* CMaterial::getExtraParams(const char *shaderPath)
{
for (SExtraParams* e : m_extras)
{
if (e->ShaderPath == shaderPath)
return e;
}

return NULL;
}

void CMaterial::saveExtraParams()
{
// get or create extra
SExtraParams *e = getExtraParams(m_shaderPath.c_str());
if (e == NULL)
{
e = new SExtraParams();
e->ShaderPath = m_shaderPath;
m_extras.push_back(e);
}

// clear old params
for (SUniformValue *&uniform : e->UniformParams)
delete uniform;
e->UniformParams.clear();

for (SUniformTexture *&uniform : e->UniformTextures)
delete uniform;
e->UniformTextures.clear();

// add current params
for (SUniformTexture *&t : m_uniformTextures)
{
e->UniformTextures.push_back(t->clone());
}

for (SUniformValue *&v : m_uniformParams)
{
e->UniformParams.push_back(v->clone());
}
}

void CMaterial::reloadExtraParams(const char *shaderPath)
{
SExtraParams *e = getExtraParams(m_shaderPath.c_str());
if (e == NULL)
{
// no extra data
// try find in same shader params
for (SUniformTexture *&t : m_uniformTextures)
{
if (t->Texture != NULL)
continue;

SUniformTexture *uniform = findExtraTexture(t->Name.c_str());
if (uniform != NULL)
{
t->Path = uniform->Path;
t->Texture = uniform->Texture;
break;
}
}

for (SUniformValue *&v : m_uniformParams)
{
SUniformValue *uniform = findExtraParam(v->Name.c_str(), v->FloatSize);
if (uniform != NULL)
{
v->FloatValue[0] = uniform->FloatValue[0];
v->FloatValue[1] = uniform->FloatValue[1];
v->FloatValue[2] = uniform->FloatValue[2];
v->FloatValue[3] = uniform->FloatValue[3];
break;
}
}

return;
}

for (SUniformTexture *&t : m_uniformTextures)
{
if (t->Texture != NULL)
continue;

for (SUniformTexture *&uniform : e->UniformTextures)
{
if (t->Name == uniform->Name)
{
t->Path = uniform->Path;
t->Texture = uniform->Texture;
break;
}
}
}

for (SUniformValue *&v : m_uniformParams)
{
for (SUniformValue *&uniform : e->UniformParams)
{
if (v->Name == uniform->Name && v->FloatSize == uniform->FloatSize)
{
v->FloatValue[0] = uniform->FloatValue[0];
v->FloatValue[1] = uniform->FloatValue[1];
v->FloatValue[2] = uniform->FloatValue[2];
v->FloatValue[3] = uniform->FloatValue[3];
break;
}
}
}
}

CMaterial::SUniformTexture *CMaterial::findExtraTexture(const char *name)
{
for (SExtraParams* e : m_extras)
{
for (CMaterial::SUniformTexture *t : e->UniformTextures)
{
if (t->Name == name && t->Texture != NULL)
return t;
}
}

return NULL;
}

CMaterial::SUniformValue *CMaterial::findExtraParam(const char *name, int floatSize)
{
for (SExtraParams* e : m_extras)
{
for (CMaterial::SUniformValue *v : e->UniformParams)
{
if (v->Name == name && v->FloatSize == floatSize)
return v;
}
}

return NULL;
}
}
49 changes: 48 additions & 1 deletion Projects/Skylicht/Engine/Source/Material/CMaterial.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ namespace Skylicht
}
};

struct SExtraParams
{
std::string ShaderPath;
std::vector<SUniformValue*> UniformParams;
std::vector<SUniformTexture*> UniformTextures;
};

private:
CShaderParams m_shaderParams;

Expand All @@ -91,9 +98,11 @@ namespace Skylicht

std::vector<IMeshBuffer*> m_meshBuffers;

std::vector<SExtraParams*> m_extras;

ITexture *m_resourceTexture[MATERIAL_MAX_TEXTURES];
ITexture *m_textures[MATERIAL_MAX_TEXTURES];
ITexture *m_overrideTextures[CShader::RResourceCount];
ITexture *m_overrideTextures[CShader::ResourceCount];

video::E_COMPARISON_FUNC m_zBuffer;
bool m_zWriteEnable;
Expand Down Expand Up @@ -121,9 +130,15 @@ namespace Skylicht
return m_materialName.c_str();
}

inline const char* getShaderPath()
{
return m_shaderPath.c_str();
}

CMaterial* clone(CGameObject *gameObject);

void deleteAllParams();
void deleteExtramParams();

void setUniform(const char *name, float f);
void setUniform2(const char *name, float *f);
Expand All @@ -135,6 +150,21 @@ namespace Skylicht
void setUniformTexture(const char *name, const char *path, std::vector<std::string>& folder, bool loadTexture = true);
void setUniformTexture(const char *name, ITexture *texture);

inline std::vector<SUniformValue*>& getUniformParams()
{
return m_uniformParams;
}

inline std::vector<SUniformTexture*>& getUniformTexture()
{
return m_uniformTextures;
}

inline std::vector<SExtraParams*>& getExtraParams()
{
return m_extras;
}

SUniformValue* getUniform(const char *name);

SUniformTexture* getUniformTexture(const char *name);
Expand Down Expand Up @@ -166,11 +196,18 @@ namespace Skylicht

public:

void changeShader(CShader *shader);

void changeShader(const char *path);

void autoDetectLoadTexture();

void applyMaterial();

void applyMaterial(SMaterial& mat);

protected:

void initDefaultValue();

void updateTexture(SMaterial& mat);
Expand All @@ -186,6 +223,16 @@ namespace Skylicht
SUniformTexture *newUniformTexture(const char *name);

void addShaderUI(CShader::SUniformUI* ui);

SExtraParams* getExtraParams(const char *shaderPath);

void saveExtraParams();

void reloadExtraParams(const char *shaderPath);

SUniformTexture *findExtraTexture(const char *name);

SUniformValue *findExtraParam(const char *name, int floatSize);
};

typedef std::vector<CMaterial*> ArrayMaterial;
Expand Down
Loading

0 comments on commit b489da9

Please sign in to comment.