1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-07-03 14:34:34 +00:00

Improvements to shader API; use handles instead of raw pointers.

This commit is contained in:
fgenesis 2013-06-15 04:11:11 +02:00
parent 486e8f92ad
commit 6962a3e3ab
5 changed files with 145 additions and 67 deletions

View file

@ -378,7 +378,6 @@ static void compile_time_assertions()
compile_assert(oo(Path) == oo(Avatar)); compile_assert(oo(Path) == oo(Avatar));
compile_assert(oo(Path) == oo(BaseText)); compile_assert(oo(Path) == oo(BaseText));
compile_assert(oo(Path) == oo(PauseQuad)); compile_assert(oo(Path) == oo(PauseQuad));
compile_assert(oo(Path) == oo(Shader));
#undef oo #undef oo
} }
#endif #endif
@ -7750,6 +7749,7 @@ luaFunc(text_setWidth)
luaFunc(loadShader) luaFunc(loadShader)
{ {
int handle = 0;
const char *vertRaw = getCString(L, 1); const char *vertRaw = getCString(L, 1);
const char *fragRaw = getCString(L, 2); const char *fragRaw = getCString(L, 2);
std::string vert, frag; std::string vert, frag;
@ -7757,62 +7757,68 @@ luaFunc(loadShader)
findFile_helper(vertRaw, vert); findFile_helper(vertRaw, vert);
if(fragRaw) if(fragRaw)
findFile_helper(fragRaw, frag); findFile_helper(fragRaw, frag);
Shader *sh = new Shader();
sh->load(vert, frag); if(core->afterEffectManager)
if(!sh->isLoaded()) handle = core->afterEffectManager->loadShaderFile(vert.c_str(), frag.c_str());
{
delete sh; luaReturnInt(handle);
sh = NULL;
}
luaReturnPtr(sh);
} }
luaFunc(createShader) luaFunc(createShader)
{ {
Shader *sh = new Shader(); int handle = 0;
sh->loadSrc(getCString(L, 1), getCString(L, 2)); if(core->afterEffectManager)
if(!sh->isLoaded()) handle = core->afterEffectManager->loadShaderSrc(getCString(L, 1), getCString(L, 2));
{ luaReturnInt(handle);
delete sh;
sh = NULL;
}
luaReturnPtr(sh);
} }
luaFunc(shader_setAsAfterEffect) luaFunc(shader_setAsAfterEffect)
{ {
int idx = lua_tointeger(L, 2); int handle = lua_tointeger(L, 1);
if(idx < core->afterEffectManager->scriptShader.size()) int pos = lua_tointeger(L, 2);
core->afterEffectManager->scriptShader[idx] = lua_isuserdata(L, 1) ? getShader(L, 1) : NULL; bool done = false;
if(core->afterEffectManager)
done = core->afterEffectManager->setShaderPipelinePos(handle, pos);
luaReturnBool(done);
}
luaFunc(shader_setNumAfterEffects)
{
if(core->afterEffectManager)
core->afterEffectManager->setShaderPipelineSize(lua_tointeger(L, 1));
luaReturnNil(); luaReturnNil();
} }
luaFunc(shader_setInt) luaFunc(shader_setInt)
{ {
Shader *sh = getShader(L, 1); if(core->afterEffectManager)
const char *name = getCString(L, 2); {
if(sh && name) Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6)); const char *name = getCString(L, 2);
if(sh && name)
sh->setInt(name, lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5), lua_tointeger(L, 6));
}
luaReturnNil(); luaReturnNil();
} }
luaFunc(shader_setFloat) luaFunc(shader_setFloat)
{ {
Shader *sh = getShader(L, 1); if(core->afterEffectManager)
const char *name = getCString(L, 2); {
if(sh && name) Shader *sh = core->afterEffectManager->getShaderPtr(lua_tointeger(L, 1));
sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6)); const char *name = getCString(L, 2);
if(sh && name)
sh->setFloat(name, lua_tonumber(L, 3), lua_tonumber(L, 4), lua_tonumber(L, 5), lua_tonumber(L, 6));
}
luaReturnNil(); luaReturnNil();
} }
luaFunc(shader_delete) luaFunc(shader_delete)
{ {
Shader *sh = getShader(L); if(core->afterEffectManager)
delete sh; core->afterEffectManager->unloadShader(lua_tointeger(L, 1));
size_t sz = core->afterEffectManager->scriptShader.size();
for(size_t i = 0; i < sz; ++i)
if(core->afterEffectManager->scriptShader[i] == sh)
core->afterEffectManager->scriptShader[i] = NULL;
luaReturnNil(); luaReturnNil();
} }
@ -8693,6 +8699,7 @@ static const struct {
luaRegister(loadShader), luaRegister(loadShader),
luaRegister(createShader), luaRegister(createShader),
luaRegister(shader_setAsAfterEffect), luaRegister(shader_setAsAfterEffect),
luaRegister(shader_setNumAfterEffects),
luaRegister(shader_setFloat), luaRegister(shader_setFloat),
luaRegister(shader_setInt), luaRegister(shader_setInt),
luaRegister(shader_delete), luaRegister(shader_delete),

View file

@ -34,7 +34,7 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
active = false; active = false;
numEffects = 0; numEffects = 0;
bRenderGridPoints = true; bRenderGridPoints = true;
scriptShader.resize(10, 0); shaderPipeline.resize(10, 0);
screenWidth = core->getWindowWidth(); screenWidth = core->getWindowWidth();
screenHeight = core->getWindowHeight(); screenHeight = core->getWindowHeight();
@ -65,26 +65,7 @@ void AfterEffectManager::loadShaders()
{ {
deleteShaders(); deleteShaders();
Shader *sh = new Shader(); // ...Load shaders here...
sh->load("data/shaders/test.vert", "data/shaders/test.frag");
if(sh->isLoaded())
scriptShader[0] = sh;
else
delete sh;
sh = new Shader();
sh->load("data/shaders/test2.vert", "data/shaders/test2.frag");
if(sh->isLoaded())
scriptShader[1] = sh;
else
delete sh;
sh = new Shader();
sh->load("data/shaders/test3.vert", "data/shaders/test3.frag");
if(sh->isLoaded())
scriptShader[2] = sh;
else
delete sh;
} }
AfterEffectManager::~AfterEffectManager() AfterEffectManager::~AfterEffectManager()
@ -119,12 +100,15 @@ void AfterEffectManager::deleteEffects()
void AfterEffectManager::deleteShaders() void AfterEffectManager::deleteShaders()
{ {
for(size_t i = 0; i < scriptShader.size(); ++i) for(size_t i = 0; i < shaderPipeline.size(); ++i)
shaderPipeline[i] = 0;
for(size_t i = 0; i < loadedShaders.size(); ++i)
{ {
if(scriptShader[i]) if(loadedShaders[i])
{ {
delete scriptShader[i]; delete loadedShaders[i];
scriptShader[i] = 0; loadedShaders[i] = 0;
} }
} }
} }
@ -210,14 +194,14 @@ void AfterEffectManager::renderGrid()
int firstShader = -1; int firstShader = -1;
int lastShader = -1; int lastShader = -1;
Shader *activeShader = 0; Shader *activeShader = 0;
for (size_t i = 0; i < scriptShader.size(); ++i) for (size_t i = 0; i < shaderPipeline.size(); ++i)
{ {
if(scriptShader[i]) if(shaderPipeline[i])
{ {
if(firstShader < 0) if(firstShader < 0)
{ {
firstShader = i; firstShader = i;
activeShader = scriptShader[i]; activeShader = shaderPipeline[i];
} }
lastShader = i; lastShader = i;
} }
@ -290,7 +274,7 @@ void AfterEffectManager::renderGrid()
for(int i = firstShader + 1; i <= lastShader; ++i) for(int i = firstShader + 1; i <= lastShader; ++i)
{ {
activeShader = scriptShader[i]; activeShader = shaderPipeline[i];
if(!activeShader) if(!activeShader)
continue; continue;
@ -567,3 +551,79 @@ void RippleEffect::update(float dt, Vector ** drawGrid, int xDivs, int yDivs)
} }
} }
} }
int AfterEffectManager::loadShaderFile(const char *vert, const char *frag)
{
Shader *sh = new Shader();
sh->load(vert, frag);
if(!sh->isLoaded())
{
delete sh;
return 0;
}
return _insertShader(sh);
}
int AfterEffectManager::loadShaderSrc(const char *vert, const char *frag)
{
Shader *sh = new Shader();
sh->loadSrc(vert, frag);
if(!sh->isLoaded())
{
delete sh;
return 0;
}
return _insertShader(sh);
}
Shader *AfterEffectManager::getShaderPtr(int handle)
{
size_t idx = handle - 1;
return idx < loadedShaders.size() ? loadedShaders[idx] : 0;
}
void AfterEffectManager::setShaderPipelineSize(size_t size)
{
shaderPipeline.resize(size, 0);
}
bool AfterEffectManager::setShaderPipelinePos(int handle, size_t pos)
{
if(pos < shaderPipeline.size())
{
shaderPipeline[pos] = getShaderPtr(handle);
return true;
}
return false;
}
// returns handle (= index + 1)
int AfterEffectManager::_insertShader(Shader *sh)
{
for(size_t i = 0; i < loadedShaders.size(); ++i)
{
if(!loadedShaders[i])
{
loadedShaders[i] = sh;
return i+1;
}
}
loadedShaders.push_back(sh);
return loadedShaders.size();
}
void AfterEffectManager::unloadShader(int handle)
{
Shader *sh = getShaderPtr(handle);
if(!sh)
return;
for(size_t i = 0; i < shaderPipeline.size(); ++i)
if(shaderPipeline[i] == sh)
shaderPipeline[i] = 0;
size_t idx = handle - 1;
loadedShaders[idx] = 0;
delete sh;
}

View file

@ -108,11 +108,23 @@ public:
int screenWidth, screenHeight; int screenWidth, screenHeight;
int textureWidth, textureHeight; int textureWidth, textureHeight;
std::vector<Shader*> scriptShader; Vector ** drawGrid;
Vector ** drawGrid; // returns handle > 0 on success
int loadShaderFile(const char *vert, const char *frag);
int loadShaderSrc(const char *vert, const char *frag);
Shader *getShaderPtr(int handle);
void setShaderPipelineSize(size_t size);
bool setShaderPipelinePos(int handle, size_t pos);
void unloadShader(int handle);
protected:
int _insertShader(Shader *sh);
std::vector<Shader*> shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once.
std::vector<Shader*> loadedShaders;
FrameBuffer backupBuffer; FrameBuffer backupBuffer;
}; };

View file

@ -131,7 +131,6 @@ end:
Shader::Shader() Shader::Shader()
{ {
addType(SCO_SHADER);
numUniforms = -1; numUniforms = -1;
uniformsDirty = false; uniformsDirty = false;

View file

@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "Base.h" #include "Base.h"
#include "ScriptObject.h" #include "ScriptObject.h"
class Shader : public ScriptObject class Shader
{ {
public: public:
Shader(); Shader();