mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-02-11 14:44:07 +00:00
Reload shaders on resolution change.
This commit is contained in:
parent
fa6ca8d60a
commit
69e25640fb
4 changed files with 58 additions and 21 deletions
|
@ -113,6 +113,13 @@ void AfterEffectManager::deleteShaders()
|
|||
}
|
||||
}
|
||||
|
||||
void AfterEffectManager::unloadShaders()
|
||||
{
|
||||
for(size_t i = 0; i < loadedShaders.size(); ++i)
|
||||
if(loadedShaders[i])
|
||||
loadedShaders[i]->unload();
|
||||
}
|
||||
|
||||
void AfterEffectManager::clear()
|
||||
{
|
||||
deleteEffects();
|
||||
|
@ -196,7 +203,7 @@ void AfterEffectManager::renderGrid()
|
|||
Shader *activeShader = 0;
|
||||
for (size_t i = 0; i < shaderPipeline.size(); ++i)
|
||||
{
|
||||
if(shaderPipeline[i])
|
||||
if(shaderPipeline[i] && shaderPipeline[i]->isLoaded())
|
||||
{
|
||||
if(firstShader < 0)
|
||||
{
|
||||
|
@ -275,7 +282,7 @@ void AfterEffectManager::renderGrid()
|
|||
for(int i = firstShader + 1; i <= lastShader; ++i)
|
||||
{
|
||||
activeShader = shaderPipeline[i];
|
||||
if(!activeShader)
|
||||
if(!(activeShader && activeShader->isLoaded()))
|
||||
continue;
|
||||
|
||||
// Swap and exchange framebuffers. The old output buffer serves as texture input for the other one
|
||||
|
@ -373,7 +380,7 @@ void AfterEffectManager::renderGridPoints()
|
|||
void AfterEffectManager::unloadDevice()
|
||||
{
|
||||
backupBuffer.unloadDevice();
|
||||
deleteShaders();
|
||||
unloadShaders();
|
||||
}
|
||||
|
||||
void AfterEffectManager::reloadDevice()
|
||||
|
@ -399,7 +406,22 @@ void AfterEffectManager::reloadDevice()
|
|||
else
|
||||
backupBuffer.init(-1, -1, true);
|
||||
|
||||
loadShaders();
|
||||
for (size_t i = 0; i < loadedShaders.size(); ++i)
|
||||
{
|
||||
if (Shader *sh = loadedShaders[i])
|
||||
{
|
||||
sh->reload();
|
||||
if (!sh->isLoaded())
|
||||
{
|
||||
debugLog("AfterEffect::reloadDevice(): Failed to reload shader");
|
||||
delete sh;
|
||||
loadedShaders[i] = 0;
|
||||
for(size_t j = 0; j < shaderPipeline.size(); ++j)
|
||||
if(sh == shaderPipeline[j])
|
||||
shaderPipeline[j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AfterEffectManager::addEffect(Effect *e)
|
||||
|
@ -612,7 +634,7 @@ int AfterEffectManager::_insertShader(Shader *sh)
|
|||
return loadedShaders.size();
|
||||
}
|
||||
|
||||
void AfterEffectManager::unloadShader(int handle)
|
||||
void AfterEffectManager::deleteShader(int handle)
|
||||
{
|
||||
Shader *sh = getShaderPtr(handle);
|
||||
if(!sh)
|
||||
|
|
|
@ -91,6 +91,7 @@ public:
|
|||
void renderGridPoints();
|
||||
|
||||
void loadShaders();
|
||||
void unloadShaders(); // unloads shaders but keeps code and data intact, so that they can be reloaded.
|
||||
void deleteShaders();
|
||||
|
||||
void unloadDevice();
|
||||
|
@ -116,7 +117,7 @@ public:
|
|||
Shader *getShaderPtr(int handle);
|
||||
void setShaderPipelineSize(size_t size);
|
||||
bool setShaderPipelinePos(int handle, size_t pos);
|
||||
void unloadShader(int handle);
|
||||
void deleteShader(int handle);
|
||||
|
||||
protected:
|
||||
int _insertShader(Shader *sh);
|
||||
|
|
|
@ -164,7 +164,10 @@ bool Shader::isLoaded() const
|
|||
|
||||
void Shader::reload()
|
||||
{
|
||||
if (vertFile.size() || fragFile.size())
|
||||
load(vertFile, fragFile);
|
||||
else
|
||||
loadSrc(vertSrc.c_str(), fragSrc.c_str());
|
||||
}
|
||||
|
||||
void Shader::bind()
|
||||
|
@ -321,6 +324,9 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode)
|
|||
return;
|
||||
}
|
||||
|
||||
vertSrc = vertCode ? vertCode : "";
|
||||
fragSrc = fragCode ? fragCode : "";
|
||||
|
||||
_queryUniforms();
|
||||
|
||||
#endif
|
||||
|
@ -328,15 +334,6 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode)
|
|||
|
||||
void Shader::_setUniform(Uniform *u)
|
||||
{
|
||||
/*if(u->location == -1)
|
||||
{
|
||||
u->location = glGetUniformLocationARB(g_programObj, u->name);
|
||||
if(u->location == -1)
|
||||
{
|
||||
u->dirty = false;
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
switch(u->type)
|
||||
{
|
||||
case GL_FLOAT: glUniform1fvARB(u->location, 1, u->data.f); break;
|
||||
|
@ -381,9 +378,13 @@ void Shader::_queryUniforms()
|
|||
glGetObjectParameterivARB(g_programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB , &numUniforms);
|
||||
|
||||
if (numUniforms <= 0)
|
||||
{
|
||||
uniforms.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
uniforms.reserve(numUniforms);
|
||||
size_t total = 0;
|
||||
|
||||
for (unsigned int i = 0; i < numUniforms; ++i)
|
||||
{
|
||||
|
@ -396,15 +397,27 @@ void Shader::_queryUniforms()
|
|||
u.location = glGetUniformLocationARB(g_programObj, u.name);
|
||||
if(u.location == -1)
|
||||
continue;
|
||||
u.dirty = false;
|
||||
u.type = type;
|
||||
memset(&u.data, 0, sizeof(u.data));
|
||||
|
||||
bool add = total >= uniforms.size();
|
||||
if(add || type != u.type) // keep data intact on reload
|
||||
memset(&u.data, 0, sizeof(u.data));
|
||||
u.dirty = true;
|
||||
u.type = type;
|
||||
|
||||
if(add)
|
||||
uniforms.push_back(u);
|
||||
else
|
||||
uniforms[total] = u;
|
||||
|
||||
++total;
|
||||
}
|
||||
|
||||
uniforms.resize(total);
|
||||
|
||||
// sort to be able to do binary search later
|
||||
std::sort(uniforms.begin(), uniforms.end());
|
||||
|
||||
uniformsDirty = true;
|
||||
}
|
||||
|
||||
int Shader::_getUniformIndex(const char *name)
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
|
||||
protected:
|
||||
std::string vertFile, fragFile;
|
||||
std::string vertSrc, fragSrc;
|
||||
#ifdef BBGE_BUILD_OPENGL
|
||||
GLuint g_programObj;
|
||||
int numUniforms;
|
||||
|
@ -72,7 +73,7 @@ private:
|
|||
float f[4];
|
||||
};
|
||||
} data;
|
||||
char name[32];
|
||||
char name[64];
|
||||
|
||||
bool operator< (const Uniform&) const;
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue