1
0
Fork 0
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:
fgenesis 2013-10-25 01:44:34 +02:00
parent fa6ca8d60a
commit 69e25640fb
4 changed files with 58 additions and 21 deletions

View file

@ -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() void AfterEffectManager::clear()
{ {
deleteEffects(); deleteEffects();
@ -196,7 +203,7 @@ void AfterEffectManager::renderGrid()
Shader *activeShader = 0; Shader *activeShader = 0;
for (size_t i = 0; i < shaderPipeline.size(); ++i) for (size_t i = 0; i < shaderPipeline.size(); ++i)
{ {
if(shaderPipeline[i]) if(shaderPipeline[i] && shaderPipeline[i]->isLoaded())
{ {
if(firstShader < 0) if(firstShader < 0)
{ {
@ -275,7 +282,7 @@ void AfterEffectManager::renderGrid()
for(int i = firstShader + 1; i <= lastShader; ++i) for(int i = firstShader + 1; i <= lastShader; ++i)
{ {
activeShader = shaderPipeline[i]; activeShader = shaderPipeline[i];
if(!activeShader) if(!(activeShader && activeShader->isLoaded()))
continue; continue;
// Swap and exchange framebuffers. The old output buffer serves as texture input for the other one // 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() void AfterEffectManager::unloadDevice()
{ {
backupBuffer.unloadDevice(); backupBuffer.unloadDevice();
deleteShaders(); unloadShaders();
} }
void AfterEffectManager::reloadDevice() void AfterEffectManager::reloadDevice()
@ -399,7 +406,22 @@ void AfterEffectManager::reloadDevice()
else else
backupBuffer.init(-1, -1, true); 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) void AfterEffectManager::addEffect(Effect *e)
@ -612,7 +634,7 @@ int AfterEffectManager::_insertShader(Shader *sh)
return loadedShaders.size(); return loadedShaders.size();
} }
void AfterEffectManager::unloadShader(int handle) void AfterEffectManager::deleteShader(int handle)
{ {
Shader *sh = getShaderPtr(handle); Shader *sh = getShaderPtr(handle);
if(!sh) if(!sh)

View file

@ -91,6 +91,7 @@ public:
void renderGridPoints(); void renderGridPoints();
void loadShaders(); void loadShaders();
void unloadShaders(); // unloads shaders but keeps code and data intact, so that they can be reloaded.
void deleteShaders(); void deleteShaders();
void unloadDevice(); void unloadDevice();
@ -116,7 +117,7 @@ public:
Shader *getShaderPtr(int handle); Shader *getShaderPtr(int handle);
void setShaderPipelineSize(size_t size); void setShaderPipelineSize(size_t size);
bool setShaderPipelinePos(int handle, size_t pos); bool setShaderPipelinePos(int handle, size_t pos);
void unloadShader(int handle); void deleteShader(int handle);
protected: protected:
int _insertShader(Shader *sh); int _insertShader(Shader *sh);

View file

@ -164,7 +164,10 @@ bool Shader::isLoaded() const
void Shader::reload() void Shader::reload()
{ {
load(vertFile, fragFile); if (vertFile.size() || fragFile.size())
load(vertFile, fragFile);
else
loadSrc(vertSrc.c_str(), fragSrc.c_str());
} }
void Shader::bind() void Shader::bind()
@ -321,6 +324,9 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode)
return; return;
} }
vertSrc = vertCode ? vertCode : "";
fragSrc = fragCode ? fragCode : "";
_queryUniforms(); _queryUniforms();
#endif #endif
@ -328,15 +334,6 @@ void Shader::loadSrc(const char *vertCode, const char *fragCode)
void Shader::_setUniform(Uniform *u) 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) switch(u->type)
{ {
case GL_FLOAT: glUniform1fvARB(u->location, 1, u->data.f); break; 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); glGetObjectParameterivARB(g_programObj, GL_OBJECT_ACTIVE_UNIFORMS_ARB , &numUniforms);
if (numUniforms <= 0) if (numUniforms <= 0)
{
uniforms.clear();
return; return;
}
uniforms.reserve(numUniforms); uniforms.reserve(numUniforms);
size_t total = 0;
for (unsigned int i = 0; i < numUniforms; ++i) for (unsigned int i = 0; i < numUniforms; ++i)
{ {
@ -396,15 +397,27 @@ void Shader::_queryUniforms()
u.location = glGetUniformLocationARB(g_programObj, u.name); u.location = glGetUniformLocationARB(g_programObj, u.name);
if(u.location == -1) if(u.location == -1)
continue; continue;
u.dirty = false;
u.type = type;
memset(&u.data, 0, sizeof(u.data));
uniforms.push_back(u); 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 // sort to be able to do binary search later
std::sort(uniforms.begin(), uniforms.end()); std::sort(uniforms.begin(), uniforms.end());
uniformsDirty = true;
} }
int Shader::_getUniformIndex(const char *name) int Shader::_getUniformIndex(const char *name)

View file

@ -44,6 +44,7 @@ public:
protected: protected:
std::string vertFile, fragFile; std::string vertFile, fragFile;
std::string vertSrc, fragSrc;
#ifdef BBGE_BUILD_OPENGL #ifdef BBGE_BUILD_OPENGL
GLuint g_programObj; GLuint g_programObj;
int numUniforms; int numUniforms;
@ -72,7 +73,7 @@ private:
float f[4]; float f[4];
}; };
} data; } data;
char name[32]; char name[64];
bool operator< (const Uniform&) const; bool operator< (const Uniform&) const;
}; };