2011-08-03 20:05:33 +00:00
|
|
|
/*
|
|
|
|
Copyright (C) 2007, 2010 - Bit-Blot
|
|
|
|
|
|
|
|
This file is part of Aquaria.
|
|
|
|
|
|
|
|
Aquaria is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
#include "AfterEffect.h"
|
2016-07-09 02:18:40 +00:00
|
|
|
#include "RenderBase.h"
|
2016-07-17 20:25:24 +00:00
|
|
|
#include "Shader.h"
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
Effect::Effect()
|
|
|
|
{
|
|
|
|
done = false;
|
|
|
|
rate = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
|
|
|
|
{
|
|
|
|
active = false;
|
|
|
|
numEffects = 0;
|
2013-06-15 02:11:11 +00:00
|
|
|
shaderPipeline.resize(10, 0);
|
2011-08-03 20:05:33 +00:00
|
|
|
|
|
|
|
this->xDivs = xDivs;
|
|
|
|
this->yDivs = yDivs;
|
|
|
|
|
2016-11-15 12:00:30 +00:00
|
|
|
updateDevice();
|
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
loadShaders();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::loadShaders()
|
|
|
|
{
|
2013-06-15 00:38:49 +00:00
|
|
|
deleteShaders();
|
|
|
|
|
2013-06-15 02:11:11 +00:00
|
|
|
// ...Load shaders here...
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AfterEffectManager::~AfterEffectManager()
|
|
|
|
{
|
|
|
|
deleteEffects();
|
2013-06-15 00:38:49 +00:00
|
|
|
deleteShaders();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::deleteEffects()
|
|
|
|
{
|
2017-01-14 17:10:20 +00:00
|
|
|
for (size_t i = 0; i < effects.size(); i++)
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
|
|
|
if (effects[i])
|
|
|
|
{
|
|
|
|
delete effects[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
effects.clear();
|
|
|
|
numEffects=0;
|
2016-07-09 02:18:40 +00:00
|
|
|
openSpots.clear();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
void AfterEffectManager::beginCapture()
|
|
|
|
{
|
|
|
|
assert(core->frameBuffer.isInited());
|
|
|
|
core->frameBuffer.pushCapture(0);
|
|
|
|
glClearColor(0,0,0,0);
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::endCapture()
|
|
|
|
{
|
|
|
|
core->frameBuffer.popCapture();
|
|
|
|
}
|
|
|
|
|
2013-06-15 00:38:49 +00:00
|
|
|
void AfterEffectManager::deleteShaders()
|
|
|
|
{
|
2013-06-15 02:11:11 +00:00
|
|
|
for(size_t i = 0; i < shaderPipeline.size(); ++i)
|
|
|
|
shaderPipeline[i] = 0;
|
|
|
|
|
|
|
|
for(size_t i = 0; i < loadedShaders.size(); ++i)
|
2013-06-15 00:38:49 +00:00
|
|
|
{
|
2013-06-15 02:11:11 +00:00
|
|
|
if(loadedShaders[i])
|
2013-06-15 00:38:49 +00:00
|
|
|
{
|
2013-06-15 02:11:11 +00:00
|
|
|
delete loadedShaders[i];
|
|
|
|
loadedShaders[i] = 0;
|
2013-06-15 00:38:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-24 23:44:34 +00:00
|
|
|
void AfterEffectManager::unloadShaders()
|
|
|
|
{
|
|
|
|
for(size_t i = 0; i < loadedShaders.size(); ++i)
|
|
|
|
if(loadedShaders[i])
|
|
|
|
loadedShaders[i]->unload();
|
|
|
|
}
|
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
void AfterEffectManager::clear()
|
|
|
|
{
|
|
|
|
deleteEffects();
|
|
|
|
resetGrid();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::update(float dt)
|
|
|
|
{
|
2016-05-05 17:40:28 +00:00
|
|
|
if (core->particlesPaused) return;
|
2011-08-03 20:05:33 +00:00
|
|
|
|
2023-08-25 19:49:16 +00:00
|
|
|
const size_t N = effects.size();
|
|
|
|
|
|
|
|
if(!N && !active)
|
|
|
|
return;
|
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
resetGrid();
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
bool isactive = false;
|
2023-08-25 19:49:16 +00:00
|
|
|
for (size_t i = 0; i < N; i++)
|
2016-05-05 17:40:28 +00:00
|
|
|
{
|
2011-08-03 20:05:33 +00:00
|
|
|
Effect *e = effects[i];
|
|
|
|
if (e)
|
|
|
|
{
|
2023-08-25 12:07:11 +00:00
|
|
|
isactive = true;
|
|
|
|
e->update(dt, grid.array2d(), xDivs, yDivs);
|
2011-08-03 20:05:33 +00:00
|
|
|
if (e->done)
|
|
|
|
{
|
|
|
|
numEffects--;
|
|
|
|
destroyEffect(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-25 12:07:11 +00:00
|
|
|
|
|
|
|
grid.updateVBO();
|
|
|
|
|
|
|
|
// FIXME: active if FBO is there and (effects exist or shaders exist)
|
|
|
|
active = isactive && core->frameBuffer.isInited();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void AfterEffectManager::resetGrid()
|
|
|
|
{
|
2023-08-25 19:49:16 +00:00
|
|
|
grid.reset01();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::destroyEffect(int id)
|
|
|
|
{
|
|
|
|
delete effects[id];
|
|
|
|
effects[id] = 0;
|
2016-07-09 02:18:40 +00:00
|
|
|
openSpots.push_back(id);
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
void AfterEffectManager::render(const RenderState& rs, unsigned fboPageWithImage) const
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2013-06-15 00:38:49 +00:00
|
|
|
assert(core->frameBuffer.isInited());
|
|
|
|
|
2012-02-19 03:57:04 +00:00
|
|
|
glPushMatrix();
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-01-11 22:05:47 +00:00
|
|
|
rs.gpu.setBlend(BLEND_DISABLED);
|
2012-02-19 03:57:04 +00:00
|
|
|
|
|
|
|
glTranslatef(core->cameraPos.x, core->cameraPos.y, 0);
|
|
|
|
glScalef(core->invGlobalScale, core->invGlobalScale,0);
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2012-02-19 03:57:04 +00:00
|
|
|
glColor4f(1,1,1,1);
|
2024-04-25 01:33:02 +00:00
|
|
|
renderGrid(rs, fboPageWithImage);
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2012-02-19 03:57:04 +00:00
|
|
|
glPopMatrix();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
void AfterEffectManager::renderGrid(const RenderState& rs, unsigned fbPage) const
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2024-04-25 01:33:02 +00:00
|
|
|
size_t firstShader, lastShader;
|
|
|
|
Shader *activeShader = NULL;
|
2013-06-15 02:11:11 +00:00
|
|
|
for (size_t i = 0; i < shaderPipeline.size(); ++i)
|
2013-06-14 22:58:32 +00:00
|
|
|
{
|
2013-10-24 23:44:34 +00:00
|
|
|
if(shaderPipeline[i] && shaderPipeline[i]->isLoaded())
|
2013-06-14 22:58:32 +00:00
|
|
|
{
|
2024-04-25 01:33:02 +00:00
|
|
|
if(!activeShader)
|
2013-06-15 00:38:49 +00:00
|
|
|
{
|
2024-04-25 01:33:02 +00:00
|
|
|
firstShader = i;
|
2013-06-15 02:11:11 +00:00
|
|
|
activeShader = shaderPipeline[i];
|
2013-06-15 00:38:49 +00:00
|
|
|
}
|
2024-04-25 01:33:02 +00:00
|
|
|
lastShader = i;
|
2013-06-14 22:58:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
// Disable blending so we don't need to clear the framebuffers
|
|
|
|
rs.gpu.setBlend(BLEND_DISABLED);
|
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
int vw = core->getVirtualWidth();
|
|
|
|
int vh = core->getVirtualHeight();
|
|
|
|
int offx = -core->getVirtualOffX();
|
|
|
|
int offy = -core->getVirtualOffY();
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
const FrameBuffer * const fb = &core->frameBuffer;
|
|
|
|
|
|
|
|
// STARTING POINT: game image was just rendered into fb(0), use that as starting point
|
|
|
|
fb->bindTexture(fbPage);
|
2013-06-15 00:38:49 +00:00
|
|
|
|
|
|
|
if(activeShader)
|
|
|
|
{
|
|
|
|
activeShader->setInt("tex", 0);
|
2024-04-25 01:33:02 +00:00
|
|
|
activeShader->bind();
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
// Unless this is the last pass, render to fb(1)
|
2013-06-15 00:38:49 +00:00
|
|
|
if(firstShader != lastShader)
|
2024-04-25 01:33:02 +00:00
|
|
|
fb->pushCapture(1 - fbPage);
|
2013-06-15 00:38:49 +00:00
|
|
|
}
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
// verts are in 0..1, transform so that we cover the entire screen
|
|
|
|
glTranslatef(offx, offy, 0);
|
|
|
|
glScalef(vw, vh, 1);
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2023-08-25 19:49:16 +00:00
|
|
|
if(active)
|
|
|
|
{
|
|
|
|
grid.render(rs);
|
|
|
|
//renderGridPoints(rs);
|
|
|
|
}
|
|
|
|
else
|
2024-04-25 01:33:02 +00:00
|
|
|
core->blitQuad.render(rs);
|
2011-08-03 20:05:33 +00:00
|
|
|
|
2013-06-14 22:58:32 +00:00
|
|
|
if (activeShader)
|
|
|
|
{
|
2024-04-25 01:33:02 +00:00
|
|
|
activeShader->unbind();
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
if(firstShader != lastShader)
|
2013-06-14 22:58:32 +00:00
|
|
|
{
|
2024-04-25 01:33:02 +00:00
|
|
|
// From here on: secondary shader passes.
|
|
|
|
// We just outputted to the backup buffer...
|
|
|
|
|
|
|
|
unsigned pageOut = 1 - fbPage;
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
for(size_t i = firstShader + 1; i <= lastShader; ++i)
|
|
|
|
{
|
|
|
|
unsigned pageIn = 1 - pageOut;
|
|
|
|
activeShader = shaderPipeline[i];
|
|
|
|
if(!(activeShader && activeShader->isLoaded()))
|
|
|
|
continue;
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
// Swap and exchange framebuffers. The old output buffer serves as texture input for the other one
|
|
|
|
pageOut = pageIn;
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
// If this is the last pass, do not render to a frame buffer again
|
|
|
|
if(i == lastShader)
|
|
|
|
fb->popCapture();
|
|
|
|
else
|
|
|
|
fb->replaceCapture(pageOut);
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
fb->bindTexture(pageIn);
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
activeShader->bind();
|
|
|
|
activeShader->setInt("tex", 0);
|
|
|
|
|
|
|
|
core->blitQuad.render(rs);
|
|
|
|
|
|
|
|
activeShader->unbind();
|
|
|
|
}
|
2013-06-14 22:58:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
RenderObject::lastTextureApplied = 0;
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
|
|
}
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
void AfterEffectManager::renderGridPoints(const RenderState& rs) const
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2023-08-25 12:07:11 +00:00
|
|
|
grid.renderDebugPoints(rs);
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::unloadDevice()
|
|
|
|
{
|
2023-08-25 12:07:11 +00:00
|
|
|
grid.dropBuffers();
|
2013-10-24 23:44:34 +00:00
|
|
|
unloadShaders();
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 12:00:30 +00:00
|
|
|
void AfterEffectManager::_updateScreenSize()
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
|
|
|
screenWidth = core->getWindowWidth();
|
|
|
|
screenHeight = core->getWindowHeight();
|
|
|
|
|
2024-04-25 01:33:02 +00:00
|
|
|
grid.setTexCoords(core->blitQuad.getTexCoords());
|
2016-11-15 12:00:30 +00:00
|
|
|
}
|
2011-08-03 20:05:33 +00:00
|
|
|
|
2016-11-15 12:00:30 +00:00
|
|
|
void AfterEffectManager::updateDevice()
|
|
|
|
{
|
|
|
|
_updateScreenSize();
|
2023-08-25 12:07:11 +00:00
|
|
|
_initGrid();
|
2016-11-15 12:00:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::reloadDevice()
|
|
|
|
{
|
|
|
|
_updateScreenSize();
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
_initGrid();
|
2013-06-15 00:38:49 +00:00
|
|
|
|
2013-10-24 23:44:34 +00:00
|
|
|
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");
|
|
|
|
loadedShaders[i] = 0;
|
|
|
|
for(size_t j = 0; j < shaderPipeline.size(); ++j)
|
|
|
|
if(sh == shaderPipeline[j])
|
|
|
|
shaderPipeline[j] = 0;
|
2016-11-15 12:00:30 +00:00
|
|
|
delete sh;
|
2013-10-24 23:44:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AfterEffectManager::addEffect(Effect *e)
|
|
|
|
{
|
|
|
|
if (!openSpots.empty())
|
|
|
|
{
|
2016-07-09 02:18:40 +00:00
|
|
|
int i = openSpots.back();
|
|
|
|
openSpots.pop_back();
|
2011-08-03 20:05:33 +00:00
|
|
|
effects[i] = e;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
effects.push_back(e);
|
|
|
|
}
|
|
|
|
numEffects++;
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2011-08-03 20:05:33 +00:00
|
|
|
e->position.x /= screenWidth;
|
|
|
|
e->position.y /= screenHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
void ShockEffect::update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs)
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
|
|
|
dt *= timeMultiplier;
|
2023-08-25 12:07:11 +00:00
|
|
|
Effect::update(dt, grid, xDivs, yDivs);
|
2011-08-03 20:05:33 +00:00
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
const Vector centerPoint = position - ((core->screenCenter-originalCenter)*core->globalScale.x)/core->width;
|
2011-08-03 20:05:33 +00:00
|
|
|
amplitude-=dt*rate;
|
|
|
|
currentDistance+=dt*frequency;
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
const float distFromCamp = 4;
|
|
|
|
const float adjWaveLength = waveLength/distFromCamp;
|
|
|
|
const float adjAmplitude = amplitude/distFromCamp;
|
|
|
|
|
2023-08-25 19:49:16 +00:00
|
|
|
const float invAdjVaveLen = -1.0f / adjWaveLength;
|
2023-08-25 12:07:11 +00:00
|
|
|
const float dist = currentDistance*adjWaveLength;
|
2011-08-03 20:05:33 +00:00
|
|
|
|
|
|
|
if (amplitude < 0)
|
|
|
|
done=true;
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
for (int y = 1; y < (yDivs-1); y++)
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2023-08-25 12:07:11 +00:00
|
|
|
Vector *row = grid.row(y);
|
|
|
|
for (int x = 1; x < (xDivs-1); x++)
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2023-08-25 19:49:16 +00:00
|
|
|
float xDist = (centerPoint.x - row[x].x)/.75f; // factor for 4:3 internal resolution
|
2023-08-25 12:07:11 +00:00
|
|
|
float yDist = centerPoint.y - row[x].y;
|
2016-05-05 17:40:28 +00:00
|
|
|
|
2016-07-09 02:18:40 +00:00
|
|
|
float tDist = sqrtf(xDist*xDist+yDist*yDist);
|
2011-08-03 20:05:33 +00:00
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
if (tDist < dist)
|
2011-08-03 20:05:33 +00:00
|
|
|
{
|
2023-08-25 19:49:16 +00:00
|
|
|
const float a = tDist * invAdjVaveLen + currentDistance;
|
2023-08-25 12:07:11 +00:00
|
|
|
row[x].x += adjAmplitude*sinf(a)*.75f;
|
|
|
|
row[x].y += adjAmplitude*cosf(a);
|
2011-08-03 20:05:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-15 02:11:11 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-08-25 12:07:11 +00:00
|
|
|
void AfterEffectManager::_initGrid()
|
|
|
|
{
|
|
|
|
if(xDivs && yDivs)
|
|
|
|
grid.init(xDivs, yDivs);
|
|
|
|
else
|
|
|
|
grid.dropBuffers();
|
|
|
|
}
|
|
|
|
|
2013-10-24 23:44:34 +00:00
|
|
|
void AfterEffectManager::deleteShader(int handle)
|
2013-06-15 02:11:11 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|