1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2025-02-13 16:16:08 +00:00

rework AfterEffect to use RenderGrid instead of its own thing

This commit is contained in:
fgenesis 2023-08-25 14:07:11 +02:00
parent 3c48349e94
commit 71f9120c30
5 changed files with 111 additions and 155 deletions

View file

@ -38,20 +38,9 @@ AfterEffectManager::AfterEffectManager(int xDivs, int yDivs)
bRenderGridPoints = true; bRenderGridPoints = true;
shaderPipeline.resize(10, 0); shaderPipeline.resize(10, 0);
drawGrid = 0;
this->xDivs = xDivs; this->xDivs = xDivs;
this->yDivs = yDivs; this->yDivs = yDivs;
if (xDivs != 0 && yDivs != 0)
{
drawGrid = new Vector * [xDivs];
for (int i = 0; i < xDivs; i++)
{
drawGrid[i] = new Vector [yDivs];
}
}
updateDevice(); updateDevice();
loadShaders(); loadShaders();
@ -66,15 +55,6 @@ void AfterEffectManager::loadShaders()
AfterEffectManager::~AfterEffectManager() AfterEffectManager::~AfterEffectManager()
{ {
if (drawGrid)
{
int i;
for (i = 0; i < xDivs; i++)
{
delete[] drawGrid[i];
}
delete[] drawGrid;
}
deleteEffects(); deleteEffects();
deleteShaders(); deleteShaders();
} }
@ -127,18 +107,14 @@ void AfterEffectManager::update(float dt)
resetGrid(); resetGrid();
if (core->frameBuffer.isInited()) bool isactive = false;
active = true;
else
active = false;
for (size_t i = 0; i < effects.size(); i++) for (size_t i = 0; i < effects.size(); i++)
{ {
Effect *e = effects[i]; Effect *e = effects[i];
if (e) if (e)
{ {
active = true; isactive = true;
e->update(dt, drawGrid, xDivs, yDivs); e->update(dt, grid.array2d(), xDivs, yDivs);
if (e->done) if (e->done)
{ {
numEffects--; numEffects--;
@ -146,19 +122,30 @@ void AfterEffectManager::update(float dt)
} }
} }
} }
grid.updateVBO();
// FIXME: active if FBO is there and (effects exist or shaders exist)
active = isactive && core->frameBuffer.isInited();
} }
void AfterEffectManager::resetGrid() void AfterEffectManager::resetGrid()
{ {
for (int i = 0; i < xDivs; i++) Array2d<Vector>& a = grid.array2d();
const float mx = 1.0f / (float)(xDivs-1);
const float my = 1.0f / (float)(yDivs-1);
for (int y = 0; y < yDivs; y++)
{ {
for (int j = 0; j < yDivs; j++) Vector *row = a.row(y);
const float yy = y * my;
for (int x = 0; x < xDivs; x++)
{ {
drawGrid[i][j].x = i/(float)(xDivs-1); row[x].x = x*mx;
drawGrid[i][j].y = j/(float)(yDivs-1); row[x].y = yy;
} }
} }
grid.needVBOUpdate = true;
} }
void AfterEffectManager::destroyEffect(int id) void AfterEffectManager::destroyEffect(int id)
@ -168,7 +155,7 @@ void AfterEffectManager::destroyEffect(int id)
openSpots.push_back(id); openSpots.push_back(id);
} }
void AfterEffectManager::render() const void AfterEffectManager::render(const RenderState& rs) const
{ {
assert(core->frameBuffer.isInited()); assert(core->frameBuffer.isInited());
@ -182,14 +169,13 @@ void AfterEffectManager::render() const
glScalef(core->invGlobalScale, core->invGlobalScale,0); glScalef(core->invGlobalScale, core->invGlobalScale,0);
glColor4f(1,1,1,1); glColor4f(1,1,1,1);
renderGrid(); renderGrid(rs);
glPopMatrix(); glPopMatrix();
} }
void AfterEffectManager::renderGrid() const void AfterEffectManager::renderGrid(const RenderState& rs) const
{ {
int firstShader = -1; int firstShader = -1;
int lastShader = -1; int lastShader = -1;
Shader *activeShader = 0; Shader *activeShader = 0;
@ -206,10 +192,6 @@ void AfterEffectManager::renderGrid() const
} }
} }
float percentX, percentY;
percentX = (float)screenWidth/(float)textureWidth;
percentY = (float)screenHeight/(float)textureHeight;
int vw = core->getVirtualWidth(); int vw = core->getVirtualWidth();
int vh = core->getVirtualHeight(); int vh = core->getVirtualHeight();
int offx = -core->getVirtualOffX(); int offx = -core->getVirtualOffX();
@ -226,32 +208,11 @@ void AfterEffectManager::renderGrid() const
backupBuffer.startCapture(); backupBuffer.startCapture();
} }
// verts are in 0..1, transform so that we cover the entire screen
glTranslatef(offx, offy, 0);
glScalef(vw, vh, 1);
for (int i = 0; i < (xDivs-1); i++) grid.render(rs);
{
for (int j = 0; j < (yDivs-1); j++)
{
glBegin(GL_QUADS);
glTexCoord2f(i/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
glVertex2f(offx + vw*drawGrid[i][j].x, offy + vh*drawGrid[i][j].y);
glTexCoord2f(i/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
glVertex2f(offx + vw*drawGrid[i][j+1].x, offy + vh*drawGrid[i][j+1].y);
glTexCoord2f((i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
glVertex2f(offx + vw*drawGrid[i+1][j+1].x, offy + vh*drawGrid[i+1][j+1].y);
glTexCoord2f((i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
glVertex2f(offx + vw*drawGrid[i+1][j].x, offy + vh*drawGrid[i+1][j].y);
glEnd();
}
}
if (activeShader) if (activeShader)
activeShader->unbind(); activeShader->unbind();
@ -263,6 +224,9 @@ void AfterEffectManager::renderGrid() const
const FrameBuffer *fbIn = &core->frameBuffer; const FrameBuffer *fbIn = &core->frameBuffer;
const FrameBuffer *fbOut = &backupBuffer; const FrameBuffer *fbOut = &backupBuffer;
const float percentX = (float)screenWidth/(float)textureWidth;
const float percentY = (float)screenHeight/(float)textureHeight;
for(int i = firstShader + 1; i <= lastShader; ++i) for(int i = firstShader + 1; i <= lastShader; ++i)
{ {
@ -282,6 +246,8 @@ void AfterEffectManager::renderGrid() const
activeShader->bind(); activeShader->bind();
activeShader->setInt("tex", 0); activeShader->setInt("tex", 0);
//blitQuad.render(rs);
// note that offx, offy are negative here! // note that offx, offy are negative here!
glBegin(GL_QUADS); glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glTexCoord2f(0.0f, 0.0f);
@ -298,70 +264,22 @@ void AfterEffectManager::renderGrid() const
} }
} }
// uncomment to render grid points
/*
glBindTexture(GL_TEXTURE_2D, 0);
glPointSize(2);
glColor4f(1, 0, 0, 0.5);
for (int i = 0; i < (xDivs-1); i++)
{
for (int j = 0; j < (yDivs-1); j++)
{
glBegin(GL_POINTS);
//glColor3f(i/div, i/div, i/div);
glTexCoord2f(i/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE0_ARB,i/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glVertex2f(800*drawGrid[i][j].x, 600*drawGrid[i][j].y);
glTexCoord2f(i/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE0_ARB,i/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,(float)(screenHeight/(yDivs-1))/16);
glVertex2f(800*drawGrid[i][j+1].x, 600*drawGrid[i][j+1].y);
glTexCoord2f((i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE0_ARB,(i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j+1)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)(screenWidth/(xDivs-1))/16,(float)(screenHeight/(yDivs-1))/16);
glVertex2f(800*drawGrid[i+1][j+1].x, 600*drawGrid[i+1][j+1].y);
glTexCoord2f((i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE0_ARB,(i+1)/(float)(xDivs-1)*percentX, 1*percentY-(j)/(float)(yDivs-1)*percentY);
//glMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)(screenWidth/(xDivs-1))/16,0);
glVertex2f(800*drawGrid[i+1][j].x, 600*drawGrid[i+1][j].y);
glEnd();
}
}
*/
//glDisable(GL_TEXTURE_2D);
RenderObject::lastTextureApplied = 0; RenderObject::lastTextureApplied = 0;
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
//bwShader.unbind();
//glActiveTextureARB(GL_TEXTURE0_ARB);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//if (bRenderGridPoints) //if (bRenderGridPoints)
// renderGridPoints(); renderGridPoints(rs);
} }
void AfterEffectManager::renderGridPoints() const void AfterEffectManager::renderGridPoints(const RenderState& rs) const
{ {
glColor4f(0.0f,0.0f,0.0f,1.0f); grid.renderDebugPoints(rs);
for (int i = 0; i < (xDivs); i++)
{
for (int j = 0; j < (yDivs); j++)
{
glBegin(GL_QUADS);
glVertex2f(screenWidth*drawGrid[i][j].x-3, screenHeight*drawGrid[i][j].y-3);
glVertex2f(screenWidth*drawGrid[i][j].x-3, screenHeight*drawGrid[i][j].y+3);
glVertex2f(screenWidth*drawGrid[i][j].x+3, screenHeight*drawGrid[i][j].y+3);
glVertex2f(screenWidth*drawGrid[i][j].x+3, screenHeight*drawGrid[i][j].y-3);
glEnd();
}
}
} }
void AfterEffectManager::unloadDevice() void AfterEffectManager::unloadDevice()
{ {
backupBuffer.unloadDevice(); backupBuffer.unloadDevice();
grid.dropBuffers();
unloadShaders(); unloadShaders();
} }
@ -382,12 +300,19 @@ void AfterEffectManager::_updateScreenSize()
textureHeight = screenHeight; textureHeight = screenHeight;
sizePowerOf2Texture(textureHeight); sizePowerOf2Texture(textureHeight);
} }
const float percentX = (float)screenWidth/(float)textureWidth;
const float percentY = (float)screenHeight/(float)textureHeight;
TexCoordBox tc = { 0, percentY, percentX, 0 }; // Y is upside down
grid.setTexCoords(tc);
blitQuad.setTexCoords(tc);
} }
void AfterEffectManager::updateDevice() void AfterEffectManager::updateDevice()
{ {
_updateScreenSize(); _updateScreenSize();
backupBuffer.init(-1, -1, true); backupBuffer.init(-1, -1, true);
_initGrid();
} }
void AfterEffectManager::reloadDevice() void AfterEffectManager::reloadDevice()
@ -395,6 +320,7 @@ void AfterEffectManager::reloadDevice()
_updateScreenSize(); _updateScreenSize();
backupBuffer.reloadDevice(); backupBuffer.reloadDevice();
_initGrid();
for (size_t i = 0; i < loadedShaders.size(); ++i) for (size_t i = 0; i < loadedShaders.size(); ++i)
{ {
@ -428,43 +354,45 @@ void AfterEffectManager::addEffect(Effect *e)
} }
numEffects++; numEffects++;
Vector base(0,0,0);
e->position.x /= screenWidth; e->position.x /= screenWidth;
e->position.y /= screenHeight; e->position.y /= screenHeight;
} }
void ShockEffect::update(float dt, Vector ** drawGrid, int xDivs, int yDivs) void ShockEffect::update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs)
{ {
dt *= timeMultiplier; dt *= timeMultiplier;
Effect::update(dt, drawGrid, xDivs, yDivs); Effect::update(dt, grid, xDivs, yDivs);
centerPoint = position; const Vector centerPoint = position - ((core->screenCenter-originalCenter)*core->globalScale.x)/core->width;
centerPoint -= ((core->screenCenter-originalCenter)*core->globalScale.x)/core->width;
amplitude-=dt*rate; amplitude-=dt*rate;
currentDistance+=dt*frequency; currentDistance+=dt*frequency;
float distFromCamp = 4; const float distFromCamp = 4;
float adjWaveLength = waveLength/distFromCamp; const float adjWaveLength = waveLength/distFromCamp;
float adjAmplitude = amplitude/distFromCamp; const float adjAmplitude = amplitude/distFromCamp;
const float m = -1.0f / (adjWaveLength+currentDistance);
const float dist = currentDistance*adjWaveLength;
if (amplitude < 0) if (amplitude < 0)
done=true; done=true;
for (int i = 1; i < (xDivs-1); i++) for (int y = 1; y < (yDivs-1); y++)
{ {
for (int j = 1; j < (yDivs-1); j++) Vector *row = grid.row(y);
for (int x = 1; x < (xDivs-1); x++)
{ {
float xDist = (centerPoint.x - drawGrid[i][j].x)/.75; float xDist = (centerPoint.x - row[x].x)/.75f;
float yDist = centerPoint.y - drawGrid[i][j].y; float yDist = centerPoint.y - row[x].y;
float tDist = sqrtf(xDist*xDist+yDist*yDist); float tDist = sqrtf(xDist*xDist+yDist*yDist);
if (tDist < currentDistance*adjWaveLength) if (tDist < dist)
{ {
drawGrid[i][j].x += adjAmplitude*sinf(-tDist/adjWaveLength+currentDistance)*.75f; const float a = tDist * m;
drawGrid[i][j].y += adjAmplitude*cosf(-tDist/adjWaveLength+currentDistance); row[x].x += adjAmplitude*sinf(a)*.75f;
row[x].y += adjAmplitude*cosf(a);
} }
} }
} }
@ -476,21 +404,25 @@ RippleEffect::RippleEffect() : Effect()
time = 0; time = 0;
} }
void RippleEffect::update(float dt, Vector ** drawGrid, int xDivs, int yDivs) void RippleEffect::update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs)
{ {
const float offx = (core->screenCenter.x/float(core->width)/2);
const float offy = (core->screenCenter.y/float(core->height)/2);
const float invx = 1.0f / float(xDivs);
time += dt*0.5f; time += dt*0.5f;
float amp = 0.002f; float amp = 0.002f;
for (int i = 0; i < (xDivs-1); i++)
{
for (int j = 0; j < (yDivs-1); j++)
{
float offset = i/float(xDivs) + (core->screenCenter.x/float(core->width)/2) +j/float(xDivs) + (core->screenCenter.y/float(core->height)/2);
drawGrid[i][j].x += sinf((time+offset)*7.5f)*(amp*0.5f); for (int y = 0; y < (yDivs-1); y++)
drawGrid[i][j].y += cosf((time+offset)*7.5f)*amp; {
float offbase = y*invx + offx + offy;
Vector *row = grid.row(y);
for (int x = 0; x < (xDivs-1); x++)
{
float offset = x*invx + offbase;
float a = (time+offset)*7.5f;
row[x].x += sinf(a)*(amp*0.5f);
row[x].y += cosf(a)*amp;
} }
} }
} }
@ -555,6 +487,16 @@ int AfterEffectManager::_insertShader(Shader *sh)
return loadedShaders.size(); return loadedShaders.size();
} }
void AfterEffectManager::_initGrid()
{
if(xDivs && yDivs)
grid.init(xDivs, yDivs);
else
grid.dropBuffers();
blitQuad.init(2, 2);
}
void AfterEffectManager::deleteShader(int handle) void AfterEffectManager::deleteShader(int handle)
{ {
Shader *sh = getShaderPtr(handle); Shader *sh = getShaderPtr(handle);

View file

@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define __after_effect__ #define __after_effect__
#include "Core.h" #include "Core.h"
#include "RenderGrid.h"
class Shader; class Shader;
@ -31,7 +32,7 @@ public:
Effect(); Effect();
virtual ~Effect(){} virtual ~Effect(){}
virtual void go(){} virtual void go(){}
virtual void update(float dt, Vector ** drawGrid, int xDivs, int yDivs){} virtual void update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs){}
bool done; bool done;
Vector position; Vector position;
protected: protected:
@ -54,13 +55,12 @@ public:
} }
float timeMultiplier; float timeMultiplier;
void update(float dt, Vector ** drawGrid, int xDivs, int yDivs); void update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs) OVERRIDE;
float waveLength; float waveLength;
float amplitude; float amplitude;
float frequency; float frequency;
Vector centerPoint;
Vector originalCenter; Vector originalCenter;
float currentDistance; float currentDistance;
@ -70,7 +70,7 @@ class RippleEffect : public Effect
{ {
public: public:
RippleEffect(); RippleEffect();
void update(float dt, Vector ** drawGrid, int xDivs, int yDivs); void update(float dt, Array2d<Vector>& grid, int xDivs, int yDivs) OVERRIDE;
float time; float time;
}; };
@ -88,9 +88,9 @@ public:
void resetGrid(); void resetGrid();
void render() const; void render(const RenderState& rs) const;
void renderGrid() const; void renderGrid(const RenderState& rs) const;
void renderGridPoints() const; void renderGridPoints(const RenderState& rs) const;
void loadShaders(); void loadShaders();
void unloadShaders(); // unloads shaders but keeps code and data intact, so that they can be reloaded. void unloadShaders(); // unloads shaders but keeps code and data intact, so that they can be reloaded.
@ -112,7 +112,7 @@ public:
int screenWidth, screenHeight; int screenWidth, screenHeight;
int textureWidth, textureHeight; int textureWidth, textureHeight;
Vector ** drawGrid; // TODO: make this + related code use DynamicRenderGrid RenderGrid grid, blitQuad;
// returns handle > 0 on success // returns handle > 0 on success
int loadShaderFile(const char *vert, const char *frag); int loadShaderFile(const char *vert, const char *frag);
@ -125,6 +125,7 @@ public:
protected: protected:
void _updateScreenSize(); void _updateScreenSize();
int _insertShader(Shader *sh); int _insertShader(Shader *sh);
void _initGrid();
std::vector<Shader*> shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once. std::vector<Shader*> shaderPipeline; // Shaders are applied in this order. Can contain the same pointer more than once.
std::vector<Shader*> loadedShaders; std::vector<Shader*> loadedShaders;

View file

@ -1810,7 +1810,7 @@ void Core::render(int startLayer, int endLayer, bool useFrameBufferIfAvail)
} }
} }
if (afterEffectManager && afterEffectManager->active && i == afterEffectManagerLayer) if (afterEffectManager /*&& afterEffectManager->active*/ && i == afterEffectManagerLayer)
{ {
afterEffectManager->render(rs); afterEffectManager->render(rs);
} }

View file

@ -58,12 +58,11 @@ void RenderGrid::dropBuffers()
indexbuf.dropBuffer(); indexbuf.dropBuffer();
} }
void RenderGrid::init(size_t w, size_t h, const TexCoordBox& tc) void RenderGrid::init(size_t w, size_t h)
{ {
assert(w > 1 && h > 1); assert(w > 1 && h > 1);
grid.init(w, h); grid.init(w, h);
setDrawOrder((GridDrawOrder)drawOrder, true); setDrawOrder((GridDrawOrder)drawOrder, true);
this->tc = tc;
reset(); reset();
Vector *dg = grid.data(); Vector *dg = grid.data();
for(size_t i = 0; i < grid.linearsize(); ++i) for(size_t i = 0; i < grid.linearsize(); ++i)
@ -72,6 +71,12 @@ void RenderGrid::init(size_t w, size_t h, const TexCoordBox& tc)
updateVBO(); updateVBO();
} }
void RenderGrid::init(size_t w, size_t h, const TexCoordBox& tc)
{
this->tc = tc;
this->init(w, h);
}
void RenderGrid::reset() void RenderGrid::reset()
{ {
@ -177,6 +182,12 @@ void RenderGrid::updateVBO()
needVBOUpdate = false; needVBOUpdate = false;
} }
void RenderGrid::updateVBOIfNecessary()
{
if(needVBOUpdate)
updateVBO();
}
void RenderGrid::render_Indexed(const RenderState& rs) const void RenderGrid::render_Indexed(const RenderState& rs) const
{ {
(void)rs; (void)rs;

View file

@ -33,6 +33,7 @@ public:
~RenderGrid(); ~RenderGrid();
void dropBuffers(); void dropBuffers();
void init(size_t w, size_t h);
void init(size_t w, size_t h, const TexCoordBox& tc); void init(size_t w, size_t h, const TexCoordBox& tc);
void reset(); void reset();
void resetWithAlpha(float a); void resetWithAlpha(float a);
@ -54,6 +55,7 @@ public:
const Array2d<Vector>& array2d() const { return grid; } const Array2d<Vector>& array2d() const { return grid; }
const DynamicGPUBuffer& getVBO() const { return vbo; } const DynamicGPUBuffer& getVBO() const { return vbo; }
void updateVBO(); void updateVBO();
void updateVBOIfNecessary();
static void ResetWithAlpha(Vector* dst, size_t w, size_t h, float alpha); static void ResetWithAlpha(Vector* dst, size_t w, size_t h, float alpha);
@ -62,12 +64,12 @@ protected:
size_t trisToDraw; size_t trisToDraw;
Array2d<Vector> grid; Array2d<Vector> grid;
TexCoordBox tc; TexCoordBox tc;
bool needVBOUpdate;
void render_Indexed(const RenderState& rs) const; void render_Indexed(const RenderState& rs) const;
void render_WithAlpha(const RenderState& rs) const; void render_WithAlpha(const RenderState& rs) const;
public: public:
bool needVBOUpdate;
GridDrawOrder drawOrder; GridDrawOrder drawOrder;
}; };