mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2025-07-03 22:44:32 +00:00
split grid rendering off from Quad, to a new RenderGrid class
This commit is contained in:
parent
0f0f3e9023
commit
976ce8ff3e
12 changed files with 603 additions and 505 deletions
|
@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
#include "SplineGrid.h"
|
#include "SplineGrid.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
|
||||||
|
|
||||||
int TIMELINE_GRIDSIZE = 10;
|
int TIMELINE_GRIDSIZE = 10;
|
||||||
|
@ -958,8 +959,9 @@ void AnimationEditor::editStripKey()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(editingBone && !editingBone->getDrawGrid().empty())
|
if(editingBone && editingBone->getGrid())
|
||||||
{
|
{
|
||||||
|
RenderGrid *grid = editingBone->getGrid();
|
||||||
Animation *a = editSprite->getCurrentAnimation();
|
Animation *a = editSprite->getCurrentAnimation();
|
||||||
BoneGridInterpolator *interp = a->getBoneGridInterpolator(editingBone->boneIdx);
|
BoneGridInterpolator *interp = a->getBoneGridInterpolator(editingBone->boneIdx);
|
||||||
|
|
||||||
|
@ -973,12 +975,12 @@ void AnimationEditor::editStripKey()
|
||||||
assert(bk->controlpoints.size() == interp->bsp.ctrlX() * interp->bsp.ctrlY());
|
assert(bk->controlpoints.size() == interp->bsp.ctrlX() * interp->bsp.ctrlY());
|
||||||
|
|
||||||
splinegrid = new SplineGrid;
|
splinegrid = new SplineGrid;
|
||||||
splinegrid->drawOrder = editingBone->drawOrder;
|
RenderGrid *rgrid = splinegrid->resize(interp->bsp.ctrlX(), interp->bsp.ctrlY(), grid->width(), grid->height(), interp->bsp.degX(), interp->bsp.degY());
|
||||||
|
rgrid->drawOrder = grid->drawOrder;
|
||||||
splinegrid->setTexture(editingBone->texture->name);
|
splinegrid->setTexture(editingBone->texture->name);
|
||||||
splinegrid->setWidthHeight(editingBone->width, editingBone->height);
|
splinegrid->setWidthHeight(editingBone->width, editingBone->height);
|
||||||
splinegrid->position = Vector(400, 300);
|
splinegrid->position = Vector(400, 300);
|
||||||
//splinegrid->followCamera = 1;
|
//splinegrid->followCamera = 1;
|
||||||
splinegrid->resize(interp->bsp.ctrlX(), interp->bsp.ctrlY(), editingBone->getDrawGrid().width(), editingBone->getDrawGrid().height(), interp->bsp.degX(), interp->bsp.degY());
|
|
||||||
splinegrid->importControlPoints(&bk->controlpoints[0]);
|
splinegrid->importControlPoints(&bk->controlpoints[0]);
|
||||||
//editSprite->addChild(splinegrid, PM_STATIC, RBP_OFF, CHILD_FRONT);
|
//editSprite->addChild(splinegrid, PM_STATIC, RBP_OFF, CHILD_FRONT);
|
||||||
//editSprite->alphaMod = 0.5f;
|
//editSprite->alphaMod = 0.5f;
|
||||||
|
|
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
#include "Element.h"
|
#include "Element.h"
|
||||||
#include "Game.h"
|
#include "Game.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
|
||||||
ElementEffectData::ElementEffectData()
|
ElementEffectData::ElementEffectData()
|
||||||
: elementEffectType(EFX_NONE)
|
: elementEffectType(EFX_NONE)
|
||||||
|
@ -182,8 +183,8 @@ void Element::update(float dt)
|
||||||
updateLife(dt);
|
updateLife(dt);
|
||||||
if (eff)
|
if (eff)
|
||||||
updateEffects(dt);
|
updateEffects(dt);
|
||||||
if (!drawGrid.empty())
|
if(grid)
|
||||||
updateGrid(dt);
|
grid->update(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,26 +205,8 @@ int Element::getElementEffectIndex()
|
||||||
|
|
||||||
void Element::setGridFromWavy()
|
void Element::setGridFromWavy()
|
||||||
{
|
{
|
||||||
if (!drawGrid.empty())
|
if(grid && eff->wavy.size())
|
||||||
{
|
grid->setFromWavy(&eff->wavy[0], eff->wavy.size(), width);
|
||||||
const size_t NX = drawGrid.width() - 1;
|
|
||||||
const size_t H = drawGrid.height();
|
|
||||||
|
|
||||||
const float iw = 1.0f / float(getWidth());
|
|
||||||
for (size_t x = 0; x < NX; x++)
|
|
||||||
{
|
|
||||||
for (size_t y = 0; y < H; y++)
|
|
||||||
{
|
|
||||||
const size_t wavy_y = (H - y)-1;
|
|
||||||
if (wavy_y < 0 || wavy_y < eff->wavy.size())
|
|
||||||
{
|
|
||||||
const float tmp = eff->wavy[wavy_y].x * iw;
|
|
||||||
drawGrid(x,y).x = tmp - 0.5f;
|
|
||||||
drawGrid(x+1,y).x = tmp + 0.5f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Element::setElementEffectByIndex(int eidx)
|
void Element::setElementEffectByIndex(int eidx)
|
||||||
|
|
|
@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "Gradient.h"
|
#include "Gradient.h"
|
||||||
#include "TTFFont.h"
|
#include "TTFFont.h"
|
||||||
#include "RoundedRect.h"
|
#include "RoundedRect.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
|
||||||
#define GEM_GRAB 10
|
#define GEM_GRAB 10
|
||||||
|
|
||||||
|
@ -561,8 +562,12 @@ void WorldMapRender::setVis(WorldMapTile *tile)
|
||||||
|
|
||||||
if (visMethod == VIS_VERTEX)
|
if (visMethod == VIS_VERTEX)
|
||||||
{
|
{
|
||||||
tile->q->setSegs(MAPVIS_SUBDIV, MAPVIS_SUBDIV, 0, 0, 0, 0, 2.0, 1);
|
RenderGrid *g = tile->q->setSegs(MAPVIS_SUBDIV, MAPVIS_SUBDIV, 0, 0, 0, 0, 2.0, 1);
|
||||||
tileDataToVis(tile, tile->q->getDrawGrid());
|
if(g)
|
||||||
|
{
|
||||||
|
g->drawOrder = GRID_DRAW_WORLDMAP;
|
||||||
|
tileDataToVis(tile, g->array2d());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (visMethod == VIS_WRITE)
|
else if (visMethod == VIS_WRITE)
|
||||||
{
|
{
|
||||||
|
@ -662,7 +667,6 @@ WorldMapRender::WorldMapRender() : RenderObject(), ActionMapper()
|
||||||
q->setTexturePointer(texs[i]);
|
q->setTexturePointer(texs[i]);
|
||||||
q->position = pos;
|
q->position = pos;
|
||||||
q->alphaMod = 0;
|
q->alphaMod = 0;
|
||||||
q->drawOrder = Quad::GRID_DRAW_WORLDMAP;
|
|
||||||
|
|
||||||
tile->q = q;
|
tile->q = q;
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ public:
|
||||||
int screenWidth, screenHeight;
|
int screenWidth, screenHeight;
|
||||||
int textureWidth, textureHeight;
|
int textureWidth, textureHeight;
|
||||||
|
|
||||||
Vector ** drawGrid;
|
Vector ** drawGrid; // TODO: make this + related code use RenderGrid
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
|
@ -72,6 +72,8 @@ set(BBGE_SRCS
|
||||||
Refcounted.h
|
Refcounted.h
|
||||||
RenderBase.cpp
|
RenderBase.cpp
|
||||||
RenderBase.h
|
RenderBase.h
|
||||||
|
RenderGrid.cpp
|
||||||
|
RenderGrid.h
|
||||||
RenderObject.cpp
|
RenderObject.cpp
|
||||||
RenderObject.h
|
RenderObject.h
|
||||||
RenderObject_inline.h
|
RenderObject_inline.h
|
||||||
|
|
458
BBGE/Quad.cpp
458
BBGE/Quad.cpp
|
@ -21,135 +21,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "Quad.h"
|
#include "Quad.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
Quad::Quad(const std::string &tex, const Vector &pos)
|
Quad::Quad(const std::string &tex, const Vector &pos)
|
||||||
: RenderObject()
|
: RenderObject()
|
||||||
{
|
{
|
||||||
renderBorderColor = Vector(1,1,1);
|
|
||||||
initQuad();
|
initQuad();
|
||||||
|
renderBorderColor = Vector(1,1,1);
|
||||||
position = pos;
|
position = pos;
|
||||||
setTexture(tex);
|
setTexture(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quad::Quad() : RenderObject()
|
||||||
|
{
|
||||||
|
initQuad();
|
||||||
|
}
|
||||||
|
|
||||||
|
Quad::~Quad()
|
||||||
void Quad::setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo)
|
|
||||||
{
|
{
|
||||||
deleteGrid();
|
deleteGrid();
|
||||||
if (x == 0 || y == 0)
|
|
||||||
{
|
|
||||||
doUpdateGrid = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
doUpdateGrid = true;
|
|
||||||
this->drawGridOffsetX = dgox;
|
|
||||||
this->drawGridOffsetY = dgoy;
|
|
||||||
this->drawGridModX = dgmx;
|
|
||||||
this->drawGridModY = dgmy;
|
|
||||||
this->drawGridTimeMultiplier = dgtm;
|
|
||||||
drawGridOut = dgo;
|
|
||||||
createGrid(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
gridTimer = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::createGrid(int xd, int yd)
|
|
||||||
{
|
|
||||||
drawGrid.init(xd, yd);
|
|
||||||
resetGrid();
|
|
||||||
Vector *dg = drawGrid.data();
|
|
||||||
for(size_t i = 0; i < drawGrid.linearsize(); ++i)
|
|
||||||
dg[i].z = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::setDrawGridAlpha(size_t x, size_t y, float alpha)
|
|
||||||
{
|
|
||||||
if (x < drawGrid.width() && y < drawGrid.height())
|
|
||||||
{
|
|
||||||
drawGrid(x, y).z = alpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::setStripPoints(bool vert, const Vector *points, size_t n)
|
|
||||||
{
|
|
||||||
if (drawGrid.empty()) return;
|
|
||||||
resetGrid();
|
|
||||||
|
|
||||||
const float mul = float(n);
|
|
||||||
|
|
||||||
if (!vert) // horz
|
|
||||||
{
|
|
||||||
const size_t xmax = std::min(drawGrid.width(), n);
|
|
||||||
for (size_t y = 0; y < drawGrid.height(); y++)
|
|
||||||
{
|
|
||||||
Vector *row = drawGrid.row(y);
|
|
||||||
for (size_t x = 0; x < xmax; x++)
|
|
||||||
row[x] += points[x] * mul;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const size_t ymax = std::min(drawGrid.height(), n);
|
|
||||||
for (size_t x = 0; x < drawGrid.width(); x++)
|
|
||||||
for (size_t y = 0; y < ymax; y++)
|
|
||||||
drawGrid(x, y) += points[y] * mul;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::ResetGrid(Vector* dst, size_t w, size_t h)
|
|
||||||
{
|
|
||||||
assert(w > 1 && h > 1);
|
|
||||||
const float xMulF = 1.0f / (float)(w-1);
|
|
||||||
const float yMulF = 1.0f / (float)(h-1);
|
|
||||||
|
|
||||||
for (size_t y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
const float yval = float(y)*yMulF-0.5f;
|
|
||||||
for (size_t x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
dst->x = float(x)*xMulF-0.5f;
|
|
||||||
dst->y = yval;
|
|
||||||
++dst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::ResetGridAndAlpha(Vector* dst, size_t w, size_t h, float alpha)
|
|
||||||
{
|
|
||||||
assert(w > 1 && h > 1);
|
|
||||||
const float xMulF = 1.0f / (float)(w-1);
|
|
||||||
const float yMulF = 1.0f / (float)(h-1);
|
|
||||||
|
|
||||||
for (size_t y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
const float yval = float(y)*yMulF-0.5f;
|
|
||||||
for (size_t x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
dst->x = float(x)*xMulF-0.5f;
|
|
||||||
dst->y = yval;
|
|
||||||
dst->z = alpha;
|
|
||||||
++dst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::resetGrid()
|
|
||||||
{
|
|
||||||
if (drawGrid.empty()) return;
|
|
||||||
|
|
||||||
ResetGrid(drawGrid.data(), drawGrid.width(), drawGrid.height());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quad::initQuad()
|
void Quad::initQuad()
|
||||||
{
|
{
|
||||||
|
addType(SCO_QUAD);
|
||||||
|
borderAlpha = 0.5;
|
||||||
repeatToFillScale = Vector(1,1);
|
repeatToFillScale = Vector(1,1);
|
||||||
gridType = GRID_WAVY;
|
|
||||||
gridTimer = 0;
|
|
||||||
|
|
||||||
doUpdateGrid = false;
|
|
||||||
|
|
||||||
autoWidth = autoHeight = 0;
|
autoWidth = autoHeight = 0;
|
||||||
|
|
||||||
|
@ -157,12 +55,58 @@ void Quad::initQuad()
|
||||||
renderCenter = true;
|
renderCenter = true;
|
||||||
width = 2; height = 2;
|
width = 2; height = 2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
upperLeftTextureCoordinates = Vector(0,0);
|
upperLeftTextureCoordinates = Vector(0,0);
|
||||||
lowerRightTextureCoordinates = Vector(1,1);
|
lowerRightTextureCoordinates = Vector(1,1);
|
||||||
renderQuad = true;
|
renderQuad = true;
|
||||||
|
grid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::deleteGrid()
|
||||||
|
{
|
||||||
|
delete grid;
|
||||||
|
grid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::destroy()
|
||||||
|
{
|
||||||
|
deleteGrid();
|
||||||
|
RenderObject::destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RenderGrid *Quad::setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo)
|
||||||
|
{
|
||||||
|
RenderGrid *g = createGrid(x, y);
|
||||||
|
if(g)
|
||||||
|
g->setSegs(dgox, dgoy, dgmx, dgmy, dgtm, dgo);
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderGrid *Quad::createGrid(int xd, int yd)
|
||||||
|
{
|
||||||
|
delete grid;
|
||||||
|
return (grid = xd && yd
|
||||||
|
? new RenderGrid(xd, yd)
|
||||||
|
: NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::setDrawGridAlpha(size_t x, size_t y, float alpha)
|
||||||
|
{
|
||||||
|
if(grid)
|
||||||
|
grid->setAlpha(x, y, alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::setStripPoints(bool vert, const Vector *points, size_t n)
|
||||||
|
{
|
||||||
|
if(grid)
|
||||||
|
grid->setStripPoints(vert, points, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quad::resetGrid()
|
||||||
|
{
|
||||||
|
if(grid)
|
||||||
|
grid->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quad::_renderBorder(const RenderState& rs, Vector color, float borderalpha) const
|
void Quad::_renderBorder(const RenderState& rs, Vector color, float borderalpha) const
|
||||||
|
@ -195,27 +139,7 @@ void Quad::_renderBorder(const RenderState& rs, Vector color, float borderalpha)
|
||||||
RenderObject::lastTextureApplied = 0;
|
RenderObject::lastTextureApplied = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Quad::Quad() : RenderObject()
|
|
||||||
{
|
|
||||||
addType(SCO_QUAD);
|
|
||||||
borderAlpha = 0.5;
|
|
||||||
drawOrder = GRID_DRAW_DEFAULT;
|
|
||||||
|
|
||||||
initQuad();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::deleteGrid()
|
|
||||||
{
|
|
||||||
drawGrid.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::destroy()
|
|
||||||
{
|
|
||||||
deleteGrid();
|
|
||||||
RenderObject::destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Quad::isCoordinateInside(Vector coord, int minSize) const
|
bool Quad::isCoordinateInside(Vector coord, int minSize) const
|
||||||
{
|
{
|
||||||
|
@ -275,272 +199,28 @@ bool Quad::isCoordinateInsideWorldRect(const Vector &coord, int w, int h) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quad::updateGrid(float dt)
|
|
||||||
{
|
|
||||||
if (!doUpdateGrid) return;
|
|
||||||
|
|
||||||
if (gridType == GRID_WAVY)
|
|
||||||
{
|
|
||||||
gridTimer += dt * drawGridTimeMultiplier;
|
|
||||||
resetGrid();
|
|
||||||
size_t hx = drawGrid.width()/2;
|
|
||||||
for (size_t x = 0; x < drawGrid.width(); x++)
|
|
||||||
{
|
|
||||||
float yoffset = x * drawGridOffsetY;
|
|
||||||
float addY = 0;
|
|
||||||
if (drawGridModY != 0)
|
|
||||||
addY = cosf(gridTimer+yoffset)*drawGridModY;
|
|
||||||
for (size_t y = 0; y < drawGrid.height(); y++)
|
|
||||||
{
|
|
||||||
float xoffset = y * drawGridOffsetX;
|
|
||||||
if (drawGridModX != 0)
|
|
||||||
{
|
|
||||||
float addX = (sinf(gridTimer+xoffset)*drawGridModX);
|
|
||||||
if (drawGridOut && x < hx)
|
|
||||||
drawGrid(x,y).x += addX;
|
|
||||||
else
|
|
||||||
drawGrid(x,y).x -= addX;
|
|
||||||
}
|
|
||||||
drawGrid(x,y).y += addY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::renderGrid(const RenderState& rs) const
|
void Quad::renderGrid(const RenderState& rs) const
|
||||||
{
|
{
|
||||||
if (drawGrid.width() < 2 || drawGrid.height() < 2)
|
RenderState rx(rs);
|
||||||
return;
|
rx.color = rs.color * this->color;
|
||||||
|
rx.alpha = rs.alpha * this->alpha.x * this->alphaMod;
|
||||||
|
|
||||||
switch(drawOrder)
|
glPushMatrix();
|
||||||
{
|
glScalef(width, height, 1);
|
||||||
case GRID_DRAW_LRTB:
|
|
||||||
renderGrid_LRTB(rs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GRID_DRAW_LRBT:
|
grid->render(rx, upperLeftTextureCoordinates, lowerRightTextureCoordinates);
|
||||||
renderGrid_LRBT(rs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GRID_DRAW_WORLDMAP:
|
|
||||||
renderGridWithAlpha(rs);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// debug points
|
// debug points
|
||||||
if (RenderObject::renderCollisionShape)
|
if (RenderObject::renderCollisionShape)
|
||||||
{
|
{
|
||||||
const size_t NX = drawGrid.width()-1;
|
|
||||||
const size_t NY = drawGrid.height()-1;
|
|
||||||
const float w = this->getWidth();
|
|
||||||
const float h = this->getHeight();
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glPointSize(2);
|
grid->renderDebugPoints(rx);
|
||||||
glColor3f(1,0,0);
|
|
||||||
glBegin(GL_POINTS);
|
|
||||||
for (size_t y = 0; y < NY; y++)
|
|
||||||
{
|
|
||||||
for (size_t x = 0; x < NX; x++)
|
|
||||||
{
|
|
||||||
glVertex2f(w*drawGrid(x,y).x, h*drawGrid(x,y).y);
|
|
||||||
glVertex2f(w*drawGrid(x,y+1).x, h*drawGrid(x,y+1).y);
|
|
||||||
glVertex2f(w*drawGrid(x+1,y+1).x, h*drawGrid(x+1,y+1).y);
|
|
||||||
glVertex2f(w*drawGrid(x+1,y).x, h*drawGrid(x+1,y).y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
RenderObject::lastTextureApplied = 0;
|
RenderObject::lastTextureApplied = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Quad::renderGrid_LRTB(const RenderState& rs) const
|
|
||||||
{
|
|
||||||
const float percentX = lowerRightTextureCoordinates.x - upperLeftTextureCoordinates.x;
|
|
||||||
const float percentY = lowerRightTextureCoordinates.y - upperLeftTextureCoordinates.y;
|
|
||||||
|
|
||||||
const float baseX = upperLeftTextureCoordinates.x;
|
|
||||||
const float baseY = upperLeftTextureCoordinates.y;
|
|
||||||
|
|
||||||
const size_t NX = drawGrid.width()-1;
|
|
||||||
const size_t NY = drawGrid.height()-1;
|
|
||||||
|
|
||||||
// NOTE: These are used to avoid repeated expensive divide operations,
|
|
||||||
// but they may cause rounding error of around 1 part per million,
|
|
||||||
// which could in theory cause minor graphical glitches with broken
|
|
||||||
// OpenGL implementations. --achurch
|
|
||||||
const float incX = percentX / float(NX);
|
|
||||||
const float incY = percentY / float(NY);
|
|
||||||
|
|
||||||
const float w = this->getWidth();
|
|
||||||
const float h = this->getHeight();
|
|
||||||
|
|
||||||
const float red = rs.color.x * this->color.x;
|
|
||||||
const float green = rs.color.y * this->color.y;
|
|
||||||
const float blue = rs.color.z * this->color.z;
|
|
||||||
const float alpha = rs.alpha * this->alpha.x * this->alphaMod;
|
|
||||||
|
|
||||||
glColor4f(red, green, blue, alpha);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
float v0 = baseY;
|
|
||||||
float v1 = v0 + incY;
|
|
||||||
for (size_t y = 0; y < NY; y++, v0 = v1, v1 += incY)
|
|
||||||
{
|
|
||||||
float u0 = baseX;
|
|
||||||
float u1 = u0 + incX;
|
|
||||||
const Vector *row0 = drawGrid.row(y);
|
|
||||||
const Vector *row1 = drawGrid.row(y+1);
|
|
||||||
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
|
||||||
{
|
|
||||||
const Vector dg00 = row0[x];
|
|
||||||
const Vector dg01 = row1[x];
|
|
||||||
const Vector dg10 = row0[x+1];
|
|
||||||
const Vector dg11 = row1[x+1];
|
|
||||||
|
|
||||||
glTexCoord2f(u0, v0);
|
|
||||||
glVertex2f(w*dg00.x, h*dg00.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u0, v1);
|
|
||||||
glVertex2f(w*dg01.x, h*dg01.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u1, v1);
|
|
||||||
glVertex2f(w*dg11.x, h*dg11.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u1, v0);
|
|
||||||
glVertex2f(w*dg10.x, h*dg10.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::renderGrid_LRBT(const RenderState& rs) const
|
|
||||||
{
|
|
||||||
const float percentX = lowerRightTextureCoordinates.x - upperLeftTextureCoordinates.x;
|
|
||||||
const float percentY = upperLeftTextureCoordinates.y - lowerRightTextureCoordinates.y;
|
|
||||||
|
|
||||||
const float baseX = upperLeftTextureCoordinates.x;
|
|
||||||
const float baseY = lowerRightTextureCoordinates.y;
|
|
||||||
|
|
||||||
const size_t NX = drawGrid.width()-1;
|
|
||||||
const size_t NY = drawGrid.height()-1;
|
|
||||||
|
|
||||||
// NOTE: These are used to avoid repeated expensive divide operations,
|
|
||||||
// but they may cause rounding error of around 1 part per million,
|
|
||||||
// which could in theory cause minor graphical glitches with broken
|
|
||||||
// OpenGL implementations. --achurch
|
|
||||||
const float incX = percentX / float(NX);
|
|
||||||
const float incY = percentY / float(NY);
|
|
||||||
|
|
||||||
const float w = this->getWidth();
|
|
||||||
const float h = this->getHeight();
|
|
||||||
|
|
||||||
const float red = rs.color.x * this->color.x;
|
|
||||||
const float green = rs.color.y * this->color.y;
|
|
||||||
const float blue = rs.color.z * this->color.z;
|
|
||||||
const float alpha = rs.alpha * this->alpha.x * this->alphaMod;
|
|
||||||
|
|
||||||
glColor4f(red, green, blue, alpha);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
float v0 = baseY;
|
|
||||||
float v1 = v0 + incY;
|
|
||||||
for (size_t y = NY; y --> 0; v0 = v1, v1 += incY)
|
|
||||||
{
|
|
||||||
float u0 = baseX;
|
|
||||||
float u1 = u0 + incX;
|
|
||||||
const Vector *row0 = drawGrid.row(y+1);
|
|
||||||
const Vector *row1 = drawGrid.row(y);
|
|
||||||
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
|
||||||
{
|
|
||||||
const Vector dg00 = row0[x];
|
|
||||||
const Vector dg01 = row1[x];
|
|
||||||
const Vector dg10 = row0[x+1];
|
|
||||||
const Vector dg11 = row1[x+1];
|
|
||||||
|
|
||||||
glTexCoord2f(u0, v0);
|
|
||||||
glVertex2f(w*dg00.x, h*dg00.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u0, v1);
|
|
||||||
glVertex2f(w*dg01.x, h*dg01.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u1, v1);
|
|
||||||
glVertex2f(w*dg11.x, h*dg11.y);
|
|
||||||
|
|
||||||
glTexCoord2f(u1, v0);
|
|
||||||
glVertex2f(w*dg10.x, h*dg10.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::renderGridWithAlpha(const RenderState& rs) const
|
|
||||||
{
|
|
||||||
const float percentX = fabsf(this->lowerRightTextureCoordinates.x - this->upperLeftTextureCoordinates.x);
|
|
||||||
const float percentY = fabsf(this->upperLeftTextureCoordinates.y - this->lowerRightTextureCoordinates.y);
|
|
||||||
|
|
||||||
const float baseX =
|
|
||||||
(lowerRightTextureCoordinates.x < upperLeftTextureCoordinates.x)
|
|
||||||
? lowerRightTextureCoordinates.x : upperLeftTextureCoordinates.x;
|
|
||||||
const float baseY =
|
|
||||||
(lowerRightTextureCoordinates.y < upperLeftTextureCoordinates.y)
|
|
||||||
? lowerRightTextureCoordinates.y : upperLeftTextureCoordinates.y;
|
|
||||||
|
|
||||||
const size_t NX = drawGrid.width()-1;
|
|
||||||
const size_t NY = drawGrid.height()-1;
|
|
||||||
|
|
||||||
// NOTE: These are used to avoid repeated expensive divide operations,
|
|
||||||
// but they may cause rounding error of around 1 part per million,
|
|
||||||
// which could in theory cause minor graphical glitches with broken
|
|
||||||
// OpenGL implementations. --achurch
|
|
||||||
const float incX = percentX / float(NX);
|
|
||||||
const float incY = percentY / float(NY);
|
|
||||||
|
|
||||||
const float w = this->getWidth();
|
|
||||||
const float h = this->getHeight();
|
|
||||||
|
|
||||||
const float red = rs.color.x * this->color.x;
|
|
||||||
const float green = rs.color.y * this->color.y;
|
|
||||||
const float blue = rs.color.z * this->color.z;
|
|
||||||
const float alpha = rs.alpha * this->alpha.x * this->alphaMod;
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
float v0 = 1 - percentY + baseY;
|
|
||||||
float v1 = v0 + incY;
|
|
||||||
for (size_t y = 0; y < NY; y++, v0 = v1, v1 += incY)
|
|
||||||
{
|
|
||||||
float u0 = baseX;
|
|
||||||
float u1 = u0 + incX;
|
|
||||||
const Vector *row0 = drawGrid.row(y);
|
|
||||||
const Vector *row1 = drawGrid.row(y+1);
|
|
||||||
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
|
||||||
{
|
|
||||||
const Vector dg00 = row0[x];
|
|
||||||
const Vector dg01 = row1[x];
|
|
||||||
const Vector dg10 = row0[x+1];
|
|
||||||
const Vector dg11 = row1[x+1];
|
|
||||||
|
|
||||||
if (dg00.z != 0 || dg01.z != 0 || dg10.z != 0 || dg11.z != 0)
|
|
||||||
{
|
|
||||||
glColor4f(red, green, blue, alpha*dg00.z);
|
|
||||||
glTexCoord2f(u0, v0);
|
|
||||||
glVertex2f(w*dg00.x, h*dg00.y);
|
|
||||||
|
|
||||||
glColor4f(red, green, blue, alpha*dg01.z);
|
|
||||||
glTexCoord2f(u0, v1);
|
|
||||||
glVertex2f(w*dg01.x, h*dg01.y);
|
|
||||||
|
|
||||||
glColor4f(red, green, blue, alpha*dg11.z);
|
|
||||||
glTexCoord2f(u1, v1);
|
|
||||||
glVertex2f(w*dg11.x, h*dg11.y);
|
|
||||||
|
|
||||||
glColor4f(red, green, blue, alpha*dg10.z);
|
|
||||||
glTexCoord2f(u1, v0);
|
|
||||||
glVertex2f(w*dg10.x, h*dg10.y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Quad::repeatTextureToFill(bool on)
|
void Quad::repeatTextureToFill(bool on)
|
||||||
{
|
{
|
||||||
|
@ -556,7 +236,7 @@ void Quad::onRender(const RenderState& rs) const
|
||||||
const float _w2 = width*0.5f;
|
const float _w2 = width*0.5f;
|
||||||
const float _h2 = height*0.5f;
|
const float _h2 = height*0.5f;
|
||||||
|
|
||||||
if (drawGrid.empty())
|
if (!grid)
|
||||||
{
|
{
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
{
|
{
|
||||||
|
@ -643,9 +323,9 @@ void Quad::onUpdate(float dt)
|
||||||
else if (autoHeight == AUTO_VIRTUALHEIGHT)
|
else if (autoHeight == AUTO_VIRTUALHEIGHT)
|
||||||
height = core->getVirtualHeight();
|
height = core->getVirtualHeight();
|
||||||
|
|
||||||
if (!drawGrid.empty() && alpha.x > 0 && alphaMod > 0)
|
if (grid && alpha.x > 0 && alphaMod > 0)
|
||||||
{
|
{
|
||||||
updateGrid(dt);
|
grid->update(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
BBGE/Quad.h
57
BBGE/Quad.h
|
@ -39,12 +39,15 @@ protected:
|
||||||
void onRender(const RenderState& rs) const OVERRIDE;
|
void onRender(const RenderState& rs) const OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RenderGrid;
|
||||||
|
|
||||||
class Quad : public RenderObject
|
class Quad : public RenderObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Quad(const std::string &tex, const Vector &pos);
|
Quad(const std::string &tex, const Vector &pos);
|
||||||
Quad();
|
Quad();
|
||||||
void createGrid(int x, int y);
|
virtual ~Quad();
|
||||||
|
RenderGrid *createGrid(int x, int y);
|
||||||
void destroy() OVERRIDE;
|
void destroy() OVERRIDE;
|
||||||
bool isCoordinateInside(Vector coord, int minSize=0) const;
|
bool isCoordinateInside(Vector coord, int minSize=0) const;
|
||||||
bool isCoordinateInsideWorld(const Vector &coord, int minSize=0) const;
|
bool isCoordinateInsideWorld(const Vector &coord, int minSize=0) const;
|
||||||
|
@ -58,78 +61,44 @@ public:
|
||||||
float getWidth() const {return width;}
|
float getWidth() const {return width;}
|
||||||
float getHeight() const {return height;}
|
float getHeight() const {return height;}
|
||||||
|
|
||||||
void setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo);
|
RenderGrid *setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo);
|
||||||
void setDrawGridAlpha(size_t x, size_t y, float alpha);
|
void setDrawGridAlpha(size_t x, size_t y, float alpha);
|
||||||
void repeatTextureToFill(bool on);
|
void repeatTextureToFill(bool on);
|
||||||
void refreshRepeatTextureToFill();
|
void refreshRepeatTextureToFill();
|
||||||
bool isRepeatingTextureToFill() const { return repeatTexture; }
|
bool isRepeatingTextureToFill() const { return repeatTexture; }
|
||||||
void setStripPoints(bool vert, const Vector *points, size_t n);
|
void setStripPoints(bool vert, const Vector *points, size_t n);
|
||||||
Array2d<Vector>& getDrawGrid() { return drawGrid; }
|
RenderGrid *getGrid() { return grid; }
|
||||||
const Array2d<Vector>& getDrawGrid() const { return drawGrid; }
|
const RenderGrid *getGrid() const { return grid; }
|
||||||
|
|
||||||
void reloadDevice() OVERRIDE;
|
void reloadDevice() OVERRIDE;
|
||||||
|
|
||||||
void deleteGrid();
|
void deleteGrid();
|
||||||
|
|
||||||
|
|
||||||
Vector upperLeftTextureCoordinates, lowerRightTextureCoordinates;
|
Vector upperLeftTextureCoordinates, lowerRightTextureCoordinates;
|
||||||
|
|
||||||
enum GridDrawOrder
|
// TODO: this should be a bitmask
|
||||||
{
|
char autoWidth, autoHeight;
|
||||||
GRID_DRAW_WORLDMAP = -1, // LRTB order, uses grid.z as alpha
|
|
||||||
GRID_DRAW_LRTB = 0, // the default. ignores grid.z
|
|
||||||
GRID_DRAW_LRBT = 1, // Y axis inverted
|
|
||||||
|
|
||||||
GRID_DRAW_DEFAULT = GRID_DRAW_LRTB
|
|
||||||
};
|
|
||||||
|
|
||||||
enum GridType
|
|
||||||
{
|
|
||||||
GRID_WAVY = 0,
|
|
||||||
GRID_STRIP = 1, // quad is in strip mode
|
|
||||||
GRID_INTERP = 2, // quad is in grid mode
|
|
||||||
};
|
|
||||||
unsigned char gridType; // unsigned char to save space
|
|
||||||
|
|
||||||
char autoWidth, autoHeight; // char to save space
|
|
||||||
|
|
||||||
bool renderQuad, renderCenter, renderBorder;
|
bool renderQuad, renderCenter, renderBorder;
|
||||||
|
|
||||||
Vector texOff;
|
Vector texOff;
|
||||||
|
|
||||||
float borderAlpha;
|
float borderAlpha;
|
||||||
Vector renderBorderColor;
|
Vector renderBorderColor;
|
||||||
Vector repeatToFillScale;
|
Vector repeatToFillScale;
|
||||||
|
|
||||||
static void ResetGrid(Vector *dst, size_t w, size_t h);
|
|
||||||
static void ResetGridAndAlpha(Vector *dst, size_t w, size_t h, float alpha = 1.0f);
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float gridTimer;
|
|
||||||
Array2d<Vector> drawGrid;
|
RenderGrid *grid;
|
||||||
|
|
||||||
|
|
||||||
void resetGrid();
|
void resetGrid();
|
||||||
void updateGrid(float dt);
|
|
||||||
void renderGrid(const RenderState& rs) const;
|
void renderGrid(const RenderState& rs) const;
|
||||||
void renderGrid_LRTB(const RenderState& rs) const;
|
|
||||||
void renderGrid_LRBT(const RenderState& rs) const;
|
|
||||||
void renderGridWithAlpha(const RenderState& rs) const;
|
|
||||||
|
|
||||||
float drawGridOffsetX;
|
|
||||||
float drawGridOffsetY;
|
|
||||||
float drawGridModX;
|
|
||||||
float drawGridModY;
|
|
||||||
float drawGridTimeMultiplier;
|
|
||||||
bool drawGridOut;
|
|
||||||
|
|
||||||
void onSetTexture() OVERRIDE;
|
void onSetTexture() OVERRIDE;
|
||||||
void onRender(const RenderState& rs) const OVERRIDE;
|
void onRender(const RenderState& rs) const OVERRIDE;
|
||||||
void onUpdate(float dt) OVERRIDE;
|
void onUpdate(float dt) OVERRIDE;
|
||||||
|
|
||||||
public:
|
|
||||||
GridDrawOrder drawOrder;
|
|
||||||
private:
|
private:
|
||||||
bool doUpdateGrid;
|
|
||||||
void initQuad();
|
void initQuad();
|
||||||
void _renderBorder(const RenderState& rs, Vector color, float borderalpha) const;
|
void _renderBorder(const RenderState& rs, Vector color, float borderalpha) const;
|
||||||
};
|
};
|
||||||
|
|
381
BBGE/RenderGrid.cpp
Normal file
381
BBGE/RenderGrid.cpp
Normal file
|
@ -0,0 +1,381 @@
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
#include "RenderBase.h"
|
||||||
|
#include "RenderState.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void ResetGrid(Vector* dst, size_t w, size_t h)
|
||||||
|
{
|
||||||
|
assert(w > 1 && h > 1);
|
||||||
|
const float xMulF = 1.0f / (float)(w-1);
|
||||||
|
const float yMulF = 1.0f / (float)(h-1);
|
||||||
|
|
||||||
|
for (size_t y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
const float yval = float(y)*yMulF-0.5f;
|
||||||
|
for (size_t x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
dst->x = float(x)*xMulF-0.5f;
|
||||||
|
dst->y = yval;
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::ResetWithAlpha(Vector* dst, size_t w, size_t h, float alpha)
|
||||||
|
{
|
||||||
|
assert(w > 1 && h > 1);
|
||||||
|
const float xMulF = 1.0f / (float)(w-1);
|
||||||
|
const float yMulF = 1.0f / (float)(h-1);
|
||||||
|
|
||||||
|
for (size_t y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
const float yval = float(y)*yMulF-0.5f;
|
||||||
|
for (size_t x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
dst->x = float(x)*xMulF-0.5f;
|
||||||
|
dst->y = yval;
|
||||||
|
dst->z = alpha;
|
||||||
|
++dst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RenderGrid::RenderGrid(size_t w, size_t h)
|
||||||
|
: gridTimer(0)
|
||||||
|
, drawGridOffsetX(0), drawGridOffsetY(0), drawGridModX(0), drawGridModY(0), drawGridTimeMultiplier(0)
|
||||||
|
, drawGridOut(false), gridType(GRID_WAVY), drawOrder(GRID_DRAW_DEFAULT)
|
||||||
|
{
|
||||||
|
init(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderGrid::~RenderGrid()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::init(size_t w, size_t h)
|
||||||
|
{
|
||||||
|
assert(w > 1 && h > 1);
|
||||||
|
grid.init(w, h);
|
||||||
|
reset();
|
||||||
|
Vector *dg = grid.data();
|
||||||
|
for(size_t i = 0; i < grid.linearsize(); ++i)
|
||||||
|
dg[i].z = 1.0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderGrid::reset()
|
||||||
|
{
|
||||||
|
ResetGrid(grid.data(), grid.width(), grid.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::resetWithAlpha(float a)
|
||||||
|
{
|
||||||
|
ResetWithAlpha(grid.data(), grid.width(), grid.height(), a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::update(float dt)
|
||||||
|
{
|
||||||
|
if (gridType == GRID_WAVY)
|
||||||
|
{
|
||||||
|
gridTimer += dt * drawGridTimeMultiplier;
|
||||||
|
reset();
|
||||||
|
size_t hx = grid.width()/2;
|
||||||
|
for (size_t x = 0; x < grid.width(); x++)
|
||||||
|
{
|
||||||
|
float yoffset = x * drawGridOffsetY;
|
||||||
|
float addY = 0;
|
||||||
|
if (drawGridModY != 0)
|
||||||
|
addY = cosf(gridTimer+yoffset)*drawGridModY;
|
||||||
|
for (size_t y = 0; y < grid.height(); y++)
|
||||||
|
{
|
||||||
|
float xoffset = y * drawGridOffsetX;
|
||||||
|
if (drawGridModX != 0)
|
||||||
|
{
|
||||||
|
float addX = (sinf(gridTimer+xoffset)*drawGridModX);
|
||||||
|
if (drawGridOut && x < hx)
|
||||||
|
grid(x,y).x += addX;
|
||||||
|
else
|
||||||
|
grid(x,y).x -= addX;
|
||||||
|
}
|
||||||
|
grid(x,y).y += addY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::setAlpha(size_t x, size_t y, float a)
|
||||||
|
{
|
||||||
|
if (x < grid.width() && y < grid.height())
|
||||||
|
grid(x, y).z = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::setSegs(float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo)
|
||||||
|
{
|
||||||
|
drawGridOffsetX = dgox;
|
||||||
|
drawGridOffsetY = dgoy;
|
||||||
|
drawGridModX = dgmx;
|
||||||
|
drawGridModY = dgmy;
|
||||||
|
drawGridTimeMultiplier = dgtm;
|
||||||
|
drawGridOut = dgo;
|
||||||
|
gridTimer = 0;
|
||||||
|
gridType = GRID_WAVY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::setStripPoints(bool vert, const Vector* points, size_t n)
|
||||||
|
{
|
||||||
|
reset();
|
||||||
|
|
||||||
|
const float mul = float(n);
|
||||||
|
|
||||||
|
if (!vert) // horz
|
||||||
|
{
|
||||||
|
const size_t xmax = std::min(grid.width(), n);
|
||||||
|
for (size_t y = 0; y < grid.height(); y++)
|
||||||
|
{
|
||||||
|
Vector *row = grid.row(y);
|
||||||
|
for (size_t x = 0; x < xmax; x++)
|
||||||
|
row[x] += points[x] * mul;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const size_t ymax = std::min(grid.height(), n);
|
||||||
|
for (size_t x = 0; x < grid.width(); x++)
|
||||||
|
for (size_t y = 0; y < ymax; y++)
|
||||||
|
grid(x, y) += points[y] * mul;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::setFromWavy(const Vector* wavy, size_t len, float width)
|
||||||
|
{
|
||||||
|
const size_t NX = grid.width() - 1;
|
||||||
|
const size_t H = grid.height();
|
||||||
|
|
||||||
|
const float iw = 1.0f / width;
|
||||||
|
for (size_t x = 0; x < NX; x++) // TODO invert loop
|
||||||
|
{
|
||||||
|
for (size_t y = 0; y < H; y++)
|
||||||
|
{
|
||||||
|
const size_t wavy_y = (H - y)-1;
|
||||||
|
if (wavy_y < len)
|
||||||
|
{
|
||||||
|
const float tmp = wavy[wavy_y].x * iw;
|
||||||
|
grid(x,y).x = tmp - 0.5f;
|
||||||
|
grid(x+1,y).x = tmp + 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RenderGrid::render(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const
|
||||||
|
{
|
||||||
|
switch(drawOrder)
|
||||||
|
{
|
||||||
|
case GRID_DRAW_LRTB:
|
||||||
|
render_LRTB(rs, upperLeftTexCoords, lowerRightTexCoords);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GRID_DRAW_LRBT:
|
||||||
|
render_LRBT(rs, upperLeftTexCoords, lowerRightTexCoords);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GRID_DRAW_WORLDMAP:
|
||||||
|
render_WithAlpha(rs, upperLeftTexCoords, lowerRightTexCoords);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::renderDebugPoints(const RenderState& rs) const
|
||||||
|
{
|
||||||
|
(void)rs; // unused
|
||||||
|
|
||||||
|
glPointSize(2);
|
||||||
|
glColor3f(1,0,0);
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
const size_t NX = grid.width()-1;
|
||||||
|
const size_t NY = grid.height()-1;
|
||||||
|
for (size_t y = 0; y < NY; y++)
|
||||||
|
{
|
||||||
|
for (size_t x = 0; x < NX; x++)
|
||||||
|
{
|
||||||
|
glVertex2f(grid(x,y).x, grid(x,y).y);
|
||||||
|
glVertex2f(grid(x,y+1).x, grid(x,y+1).y);
|
||||||
|
glVertex2f(grid(x+1,y+1).x, grid(x+1,y+1).y);
|
||||||
|
glVertex2f(grid(x+1,y).x, grid(x+1,y).y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::render_LRTB(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const
|
||||||
|
{
|
||||||
|
const float percentX = lowerRightTexCoords.x - upperLeftTexCoords.x;
|
||||||
|
const float percentY = lowerRightTexCoords.y - upperLeftTexCoords.y;
|
||||||
|
|
||||||
|
const float baseX = upperLeftTexCoords.x;
|
||||||
|
const float baseY = upperLeftTexCoords.y;
|
||||||
|
|
||||||
|
const size_t NX = grid.width()-1;
|
||||||
|
const size_t NY = grid.height()-1;
|
||||||
|
|
||||||
|
// NOTE: These are used to avoid repeated expensive divide operations,
|
||||||
|
// but they may cause rounding error of around 1 part per million,
|
||||||
|
// which could in theory cause minor graphical glitches with broken
|
||||||
|
// OpenGL implementations. --achurch
|
||||||
|
const float incX = percentX / float(NX);
|
||||||
|
const float incY = percentY / float(NY);
|
||||||
|
|
||||||
|
glColor4f(rs.color.x, rs.color.y, rs.color.z, rs.alpha);
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
float v0 = baseY;
|
||||||
|
float v1 = v0 + incY;
|
||||||
|
for (size_t y = 0; y < NY; y++, v0 = v1, v1 += incY)
|
||||||
|
{
|
||||||
|
float u0 = baseX;
|
||||||
|
float u1 = u0 + incX;
|
||||||
|
const Vector *row0 = grid.row(y);
|
||||||
|
const Vector *row1 = grid.row(y+1);
|
||||||
|
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
||||||
|
{
|
||||||
|
const Vector dg00 = row0[x];
|
||||||
|
const Vector dg01 = row1[x];
|
||||||
|
const Vector dg10 = row0[x+1];
|
||||||
|
const Vector dg11 = row1[x+1];
|
||||||
|
|
||||||
|
glTexCoord2f(u0, v0);
|
||||||
|
glVertex2f(dg00.x, dg00.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u0, v1);
|
||||||
|
glVertex2f(dg01.x, dg01.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u1, v1);
|
||||||
|
glVertex2f(dg11.x, dg11.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u1, v0);
|
||||||
|
glVertex2f(dg10.x, dg10.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::render_LRBT(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const
|
||||||
|
{
|
||||||
|
const float percentX = lowerRightTexCoords.x - upperLeftTexCoords.x;
|
||||||
|
const float percentY = upperLeftTexCoords.y - lowerRightTexCoords.y;
|
||||||
|
|
||||||
|
const float baseX = upperLeftTexCoords.x;
|
||||||
|
const float baseY = lowerRightTexCoords.y;
|
||||||
|
|
||||||
|
const size_t NX = grid.width()-1;
|
||||||
|
const size_t NY = grid.height()-1;
|
||||||
|
|
||||||
|
// NOTE: These are used to avoid repeated expensive divide operations,
|
||||||
|
// but they may cause rounding error of around 1 part per million,
|
||||||
|
// which could in theory cause minor graphical glitches with broken
|
||||||
|
// OpenGL implementations. --achurch
|
||||||
|
const float incX = percentX / float(NX);
|
||||||
|
const float incY = percentY / float(NY);
|
||||||
|
|
||||||
|
glColor4f(rs.color.x, rs.color.y, rs.color.z, rs.alpha);
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
float v0 = baseY;
|
||||||
|
float v1 = v0 + incY;
|
||||||
|
for (size_t y = NY; y --> 0; v0 = v1, v1 += incY)
|
||||||
|
{
|
||||||
|
float u0 = baseX;
|
||||||
|
float u1 = u0 + incX;
|
||||||
|
const Vector *row0 = grid.row(y+1);
|
||||||
|
const Vector *row1 = grid.row(y);
|
||||||
|
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
||||||
|
{
|
||||||
|
const Vector dg00 = row0[x];
|
||||||
|
const Vector dg01 = row1[x];
|
||||||
|
const Vector dg10 = row0[x+1];
|
||||||
|
const Vector dg11 = row1[x+1];
|
||||||
|
|
||||||
|
glTexCoord2f(u0, v0);
|
||||||
|
glVertex2f(dg00.x, dg00.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u0, v1);
|
||||||
|
glVertex2f(dg01.x, dg01.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u1, v1);
|
||||||
|
glVertex2f(dg11.x, dg11.y);
|
||||||
|
|
||||||
|
glTexCoord2f(u1, v0);
|
||||||
|
glVertex2f(dg10.x, dg10.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderGrid::render_WithAlpha(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const
|
||||||
|
{
|
||||||
|
const float percentX = fabsf(lowerRightTexCoords.x - upperLeftTexCoords.x);
|
||||||
|
const float percentY = fabsf(upperLeftTexCoords.y - lowerRightTexCoords.y);
|
||||||
|
|
||||||
|
const float baseX =
|
||||||
|
(lowerRightTexCoords.x < upperLeftTexCoords.x)
|
||||||
|
? lowerRightTexCoords.x : upperLeftTexCoords.x;
|
||||||
|
const float baseY =
|
||||||
|
(lowerRightTexCoords.y < upperLeftTexCoords.y)
|
||||||
|
? lowerRightTexCoords.y : upperLeftTexCoords.y;
|
||||||
|
|
||||||
|
const size_t NX = grid.width()-1;
|
||||||
|
const size_t NY = grid.height()-1;
|
||||||
|
|
||||||
|
// NOTE: These are used to avoid repeated expensive divide operations,
|
||||||
|
// but they may cause rounding error of around 1 part per million,
|
||||||
|
// which could in theory cause minor graphical glitches with broken
|
||||||
|
// OpenGL implementations. --achurch
|
||||||
|
const float incX = percentX / float(NX);
|
||||||
|
const float incY = percentY / float(NY);
|
||||||
|
|
||||||
|
const Vector c = rs.color;
|
||||||
|
const float alpha = rs.alpha;
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
float v0 = 1 - percentY + baseY;
|
||||||
|
float v1 = v0 + incY;
|
||||||
|
for (size_t y = 0; y < NY; y++, v0 = v1, v1 += incY)
|
||||||
|
{
|
||||||
|
float u0 = baseX;
|
||||||
|
float u1 = u0 + incX;
|
||||||
|
const Vector *row0 = grid.row(y);
|
||||||
|
const Vector *row1 = grid.row(y+1);
|
||||||
|
for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX)
|
||||||
|
{
|
||||||
|
const Vector dg00 = row0[x];
|
||||||
|
const Vector dg01 = row1[x];
|
||||||
|
const Vector dg10 = row0[x+1];
|
||||||
|
const Vector dg11 = row1[x+1];
|
||||||
|
|
||||||
|
if (dg00.z != 0 || dg01.z != 0 || dg10.z != 0 || dg11.z != 0)
|
||||||
|
{
|
||||||
|
glColor4f(c.x, c.y, c.z, alpha*dg00.z);
|
||||||
|
glTexCoord2f(u0, v0);
|
||||||
|
glVertex2f(dg00.x, dg00.y);
|
||||||
|
|
||||||
|
glColor4f(c.x, c.y, c.z, alpha*dg01.z);
|
||||||
|
glTexCoord2f(u0, v1);
|
||||||
|
glVertex2f(dg01.x, dg01.y);
|
||||||
|
|
||||||
|
glColor4f(c.x, c.y, c.z, alpha*dg11.z);
|
||||||
|
glTexCoord2f(u1, v1);
|
||||||
|
glVertex2f(dg11.x, dg11.y);
|
||||||
|
|
||||||
|
glColor4f(c.x, c.y, c.z, alpha*dg10.z);
|
||||||
|
glTexCoord2f(u1, v0);
|
||||||
|
glVertex2f(dg10.x, dg10.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
73
BBGE/RenderGrid.h
Normal file
73
BBGE/RenderGrid.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef BBGE_RENDERGRID_H
|
||||||
|
#define BBGE_RENDERGRID_H
|
||||||
|
|
||||||
|
#include "Vector.h"
|
||||||
|
#include "DataStructures.h"
|
||||||
|
|
||||||
|
struct RenderState;
|
||||||
|
|
||||||
|
enum GridDrawOrder
|
||||||
|
{
|
||||||
|
GRID_DRAW_WORLDMAP = -1, // LRTB order, uses grid.z as alpha
|
||||||
|
GRID_DRAW_LRTB = 0, // the default. ignores grid.z
|
||||||
|
GRID_DRAW_LRBT = 1, // Y axis inverted
|
||||||
|
|
||||||
|
GRID_DRAW_DEFAULT = GRID_DRAW_LRTB
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GridType
|
||||||
|
{
|
||||||
|
GRID_UNDEFINED = -1,
|
||||||
|
GRID_WAVY = 0,
|
||||||
|
GRID_STRIP = 1, // quad is in strip mode
|
||||||
|
GRID_INTERP = 2, // quad is in grid mode
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderGrid
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RenderGrid(size_t w, size_t h);
|
||||||
|
~RenderGrid();
|
||||||
|
|
||||||
|
void init(size_t w, size_t h);
|
||||||
|
void reset();
|
||||||
|
void resetWithAlpha(float a);
|
||||||
|
void update(float dt);
|
||||||
|
void render(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const;
|
||||||
|
void renderDebugPoints(const RenderState& rs) const;
|
||||||
|
void setAlpha(size_t x, size_t y, float a);
|
||||||
|
void setSegs(float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo);
|
||||||
|
void setStripPoints(bool vert, const Vector *points, size_t n);
|
||||||
|
void setFromWavy(const Vector *wavy, size_t len, float width);
|
||||||
|
|
||||||
|
size_t width() const { return grid.width(); }
|
||||||
|
size_t height() const { return grid.height(); }
|
||||||
|
size_t linearsize() const { return grid.linearsize(); }
|
||||||
|
const Vector *data() const { return grid.data(); }
|
||||||
|
Vector *data() { return grid.data(); }
|
||||||
|
Array2d<Vector>& array2d() { return grid; }
|
||||||
|
const Array2d<Vector>& array2d() const { return grid; }
|
||||||
|
|
||||||
|
static void ResetWithAlpha(Vector* dst, size_t w, size_t h, float alpha);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Array2d<Vector> grid;
|
||||||
|
float gridTimer;
|
||||||
|
float drawGridOffsetX;
|
||||||
|
float drawGridOffsetY;
|
||||||
|
float drawGridModX;
|
||||||
|
float drawGridModY;
|
||||||
|
float drawGridTimeMultiplier;
|
||||||
|
bool drawGridOut;
|
||||||
|
public:
|
||||||
|
unsigned char gridType; // unsigned char to save space
|
||||||
|
unsigned char drawOrder;
|
||||||
|
|
||||||
|
void render_LRTB(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const;
|
||||||
|
void render_LRBT(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const;
|
||||||
|
void render_WithAlpha(const RenderState& rs, const Vector& upperLeftTexCoords, const Vector& lowerRightTexCoords) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#include "ReadXML.h"
|
#include "ReadXML.h"
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "SplineGrid.h"
|
#include "SplineGrid.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
|
||||||
#include <tinyxml2.h>
|
#include <tinyxml2.h>
|
||||||
using namespace tinyxml2;
|
using namespace tinyxml2;
|
||||||
|
@ -129,16 +130,9 @@ void Bone::addSegment(Bone *b)
|
||||||
|
|
||||||
void Bone::createStrip(bool vert, int num)
|
void Bone::createStrip(bool vert, int num)
|
||||||
{
|
{
|
||||||
if (!vert)
|
RenderGrid *grid = vert ? createGrid(2, num) : createGrid(num, 2);
|
||||||
{
|
|
||||||
createGrid(num, 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
createGrid(2, num);
|
|
||||||
}
|
|
||||||
stripVert = vert;
|
stripVert = vert;
|
||||||
gridType = GRID_STRIP;
|
grid->gridType = GRID_STRIP;
|
||||||
changeStrip.resize(num);
|
changeStrip.resize(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -980,6 +974,7 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
|
||||||
XMLElement *bones = xml->NewElement("Bones");
|
XMLElement *bones = xml->NewElement("Bones");
|
||||||
for (i = 0; i < this->bones.size(); i++)
|
for (i = 0; i < this->bones.size(); i++)
|
||||||
{
|
{
|
||||||
|
const RenderGrid * const grid = this->bones[i]->getGrid();
|
||||||
XMLElement *bone = xml->NewElement("Bone");
|
XMLElement *bone = xml->NewElement("Bone");
|
||||||
bone->SetAttribute("idx", (unsigned int) this->bones[i]->boneIdx);
|
bone->SetAttribute("idx", (unsigned int) this->bones[i]->boneIdx);
|
||||||
bone->SetAttribute("gfx", this->bones[i]->gfx.c_str());
|
bone->SetAttribute("gfx", this->bones[i]->gfx.c_str());
|
||||||
|
@ -1009,10 +1004,10 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
|
||||||
bone->SetAttribute("offy", this->bones[i]->offset.y);
|
bone->SetAttribute("offy", this->bones[i]->offset.y);
|
||||||
if (!this->bones[i]->prt.empty())
|
if (!this->bones[i]->prt.empty())
|
||||||
bone->SetAttribute("prt", this->bones[i]->prt.c_str());
|
bone->SetAttribute("prt", this->bones[i]->prt.c_str());
|
||||||
if(!this->bones[i]->getDrawGrid().empty() && this->bones[i]->gridType != Quad::GRID_STRIP)
|
if(grid && grid->gridType != GRID_STRIP)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << this->bones[i]->getDrawGrid().width() << " " << this->bones[i]->getDrawGrid().height();
|
os << grid->width() << " " << grid->height();
|
||||||
bone->SetAttribute("grid", os.str().c_str());
|
bone->SetAttribute("grid", os.str().c_str());
|
||||||
}
|
}
|
||||||
else if (!this->bones[i]->changeStrip.empty())
|
else if (!this->bones[i]->changeStrip.empty())
|
||||||
|
@ -1037,9 +1032,10 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
|
||||||
os << this->bones[i]->originalScale.x << " " << this->bones[i]->originalScale.y;
|
os << this->bones[i]->originalScale.x << " " << this->bones[i]->originalScale.y;
|
||||||
bone->SetAttribute("sz", os.str().c_str());
|
bone->SetAttribute("sz", os.str().c_str());
|
||||||
}
|
}
|
||||||
if(this->bones[i]->drawOrder != Quad::GRID_DRAW_DEFAULT)
|
|
||||||
|
if(grid && grid->drawOrder != GRID_DRAW_DEFAULT)
|
||||||
{
|
{
|
||||||
bone->SetAttribute("gridDrawOrder", (int)this->bones[i]->drawOrder);
|
bone->SetAttribute("gridDrawOrder", (int)grid->drawOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1132,9 +1128,10 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn)
|
||||||
Bone *bone = this->getBoneByIdx(b->idx);
|
Bone *bone = this->getBoneByIdx(b->idx);
|
||||||
if(bone)
|
if(bone)
|
||||||
{
|
{
|
||||||
|
const RenderGrid * const bgrid = bone->getGrid();
|
||||||
os << b->idx << " " << b->x << " " << b->y << " " << b->rot << " ";
|
os << b->idx << " " << b->x << " " << b->y << " " << b->rot << " ";
|
||||||
// don't want to store grid points if they can be regenerated automatically
|
// don't want to store grid points if they can be regenerated automatically
|
||||||
size_t usedGridSize = bone->gridType == Quad::GRID_INTERP ? 0 : b->grid.size();
|
size_t usedGridSize = (!bgrid || bgrid->gridType == GRID_INTERP) ? 0 : b->grid.size();
|
||||||
os << usedGridSize << " ";
|
os << usedGridSize << " ";
|
||||||
if(usedGridSize)
|
if(usedGridSize)
|
||||||
for (size_t i = 0; i < usedGridSize; i++)
|
for (size_t i = 0; i < usedGridSize; i++)
|
||||||
|
@ -1604,12 +1601,13 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
}
|
}
|
||||||
if (bone->Attribute("grid"))
|
if (bone->Attribute("grid"))
|
||||||
{
|
{
|
||||||
if(newb->getDrawGrid().empty())
|
RenderGrid *grid = newb->getGrid();
|
||||||
|
if(!grid)
|
||||||
{
|
{
|
||||||
SimpleIStringStream is(bone->Attribute("grid"), SimpleIStringStream::REUSE);
|
SimpleIStringStream is(bone->Attribute("grid"), SimpleIStringStream::REUSE);
|
||||||
int x, y;
|
int x, y;
|
||||||
is >> x >> y;
|
is >> x >> y;
|
||||||
newb->createGrid(x, y);
|
grid = newb->createGrid(x, y);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1617,11 +1615,11 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
os << "Bone idx " << newb->idx << " already has a DrawGrid, ignoring \"grid\" attribute";
|
os << "Bone idx " << newb->idx << " already has a DrawGrid, ignoring \"grid\" attribute";
|
||||||
errorLog(os.str());
|
errorLog(os.str());
|
||||||
}
|
}
|
||||||
}
|
if(const char *gdo = bone->Attribute("gridDrawOrder"))
|
||||||
if(const char *gdo = bone->Attribute("gridDrawOrder"))
|
{
|
||||||
{
|
int ord = atoi(gdo);
|
||||||
int ord = atoi(gdo);
|
grid->drawOrder = (GridDrawOrder)ord;
|
||||||
newb->drawOrder = (Quad::GridDrawOrder)ord;
|
}
|
||||||
}
|
}
|
||||||
bone = bone->NextSiblingElement("Bone");
|
bone = bone->NextSiblingElement("Bone");
|
||||||
}
|
}
|
||||||
|
@ -1809,7 +1807,6 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
for (size_t i = 0; i < this->bones.size(); i++)
|
for (size_t i = 0; i < this->bones.size(); i++)
|
||||||
{
|
{
|
||||||
Bone *bone = this->bones[i];
|
Bone *bone = this->bones[i];
|
||||||
const Array2d<Vector>& dg = bone->getDrawGrid();
|
|
||||||
BoneKeyframe *bk = newSkeletalKeyframe.getBoneKeyframe(bone->boneIdx);
|
BoneKeyframe *bk = newSkeletalKeyframe.getBoneKeyframe(bone->boneIdx);
|
||||||
if(!bk)
|
if(!bk)
|
||||||
{
|
{
|
||||||
|
@ -1845,7 +1842,8 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
debugLog(os.str());
|
debugLog(os.str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(bi->getDrawGrid().empty())
|
RenderGrid *grid = bi->getGrid();
|
||||||
|
if(!grid)
|
||||||
{
|
{
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << "Interpolator specifies bone [" << bi->boneIdx << "] that has no grid";
|
os << "Interpolator specifies bone [" << bi->boneIdx << "] that has no grid";
|
||||||
|
@ -1854,7 +1852,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
SplineType spline = SPLINE_BSPLINE;
|
SplineType spline = SPLINE_BSPLINE;
|
||||||
int cx = 3, cy = 3, degx = 3, degy = 3;
|
unsigned cx = 3, cy = 3, degx = 3, degy = 3;
|
||||||
if(const char *stype = interp->Attribute("type"))
|
if(const char *stype = interp->Attribute("type"))
|
||||||
{
|
{
|
||||||
SimpleIStringStream is(stype, SimpleIStringStream::REUSE);
|
SimpleIStringStream is(stype, SimpleIStringStream::REUSE);
|
||||||
|
@ -1883,7 +1881,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bi->gridType = Quad::GRID_INTERP;
|
grid->gridType = GRID_INTERP;
|
||||||
// bone grid should have been created via <Bone grid=... /> earlier
|
// bone grid should have been created via <Bone grid=... /> earlier
|
||||||
|
|
||||||
const char *idata = interp->Attribute("data");
|
const char *idata = interp->Attribute("data");
|
||||||
|
@ -1898,7 +1896,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn)
|
||||||
bgip.bsp.resize(cx, cy, degx, degy);
|
bgip.bsp.resize(cx, cy, degx, degy);
|
||||||
|
|
||||||
const size_t numcp = size_t(cx) * size_t(cy);
|
const size_t numcp = size_t(cx) * size_t(cy);
|
||||||
const size_t numgridp = bi->getDrawGrid().linearsize();
|
const size_t numgridp = grid->linearsize();
|
||||||
|
|
||||||
// data format: "W H [x y x y ... (W*H times)] W H x y x y ..."
|
// data format: "W H [x y x y ... (W*H times)] W H x y x y ..."
|
||||||
// ^- start of 1st keyframe ^- 2nd keyframe
|
// ^- start of 1st keyframe ^- 2nd keyframe
|
||||||
|
@ -2062,7 +2060,8 @@ void AnimationLayer::updateBones()
|
||||||
b->scale.x = lerp(bkey1->sx, bkey2->sx, dt, lerpType);
|
b->scale.x = lerp(bkey1->sx, bkey2->sx, dt, lerpType);
|
||||||
b->scale.y = lerp(bkey1->sy, bkey2->sy, dt, lerpType);
|
b->scale.y = lerp(bkey1->sy, bkey2->sy, dt, lerpType);
|
||||||
}
|
}
|
||||||
if (b->animated==Bone::ANIM_ALL && !b->changeStrip.empty() && b->gridType == Quad::GRID_STRIP)
|
RenderGrid *grid = b->getGrid();
|
||||||
|
if (grid && b->animated==Bone::ANIM_ALL && !b->changeStrip.empty() && grid->gridType == GRID_STRIP)
|
||||||
{
|
{
|
||||||
if (bkey2->grid.size() < b->changeStrip.size())
|
if (bkey2->grid.size() < b->changeStrip.size())
|
||||||
bkey2->grid.resize(b->changeStrip.size());
|
bkey2->grid.resize(b->changeStrip.size());
|
||||||
|
@ -2074,22 +2073,21 @@ void AnimationLayer::updateBones()
|
||||||
}
|
}
|
||||||
b->setStripPoints(b->stripVert, &b->changeStrip[0], b->changeStrip.size());
|
b->setStripPoints(b->stripVert, &b->changeStrip[0], b->changeStrip.size());
|
||||||
}
|
}
|
||||||
if (b->animated==Bone::ANIM_ALL && b->gridType == Quad::GRID_INTERP)
|
if (grid && b->animated==Bone::ANIM_ALL && grid->gridType == GRID_INTERP)
|
||||||
{
|
{
|
||||||
Array2d<Vector>& dg = b->getDrawGrid();
|
const size_t N = grid->linearsize();
|
||||||
const size_t N = dg.linearsize();
|
|
||||||
if(bkey1->grid.size() < N)
|
if(bkey1->grid.size() < N)
|
||||||
{
|
{
|
||||||
bkey1->grid.resize(N);
|
bkey1->grid.resize(N);
|
||||||
Quad::ResetGridAndAlpha(&bkey1->grid[0], dg.width(), dg.height(), 1.0f);
|
RenderGrid::ResetWithAlpha(&bkey1->grid[0], grid->width(), grid->height(), 1.0f);
|
||||||
}
|
}
|
||||||
if(bkey2->grid.size() < N)
|
if(bkey2->grid.size() < N)
|
||||||
{
|
{
|
||||||
bkey2->grid.resize(N);
|
bkey2->grid.resize(N);
|
||||||
Quad::ResetGridAndAlpha(&bkey2->grid[0], dg.width(), dg.height(), 1.0f);
|
RenderGrid::ResetWithAlpha(&bkey2->grid[0], grid->width(), grid->height(), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector *dst = dg.data();
|
Vector *dst = grid->data();
|
||||||
for(size_t i = 0; i < N; ++i)
|
for(size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
dst[i].x = lerp(bkey1->grid[i].x, bkey2->grid[i].x, dt, lerpType);
|
dst[i].x = lerp(bkey1->grid[i].x, bkey2->grid[i].x, dt, lerpType);
|
||||||
|
@ -2219,16 +2217,16 @@ void SkeletalSprite::selectNextBone()
|
||||||
|
|
||||||
void BoneGridInterpolator::updateGridOnly(BoneKeyframe& bk, const Bone *bone)
|
void BoneGridInterpolator::updateGridOnly(BoneKeyframe& bk, const Bone *bone)
|
||||||
{
|
{
|
||||||
const Array2d<Vector>& dg = bone->getDrawGrid();
|
const RenderGrid *grid = bone->getGrid();
|
||||||
assert(bone->boneIdx == bk.idx);
|
assert(bone->boneIdx == bk.idx);
|
||||||
assert(bk.grid.size() == dg.linearsize());
|
assert(bk.grid.size() == grid->linearsize());
|
||||||
bsp.recalc(&bk.grid[0], dg.width(), dg.height(), &bk.controlpoints[0]);
|
bsp.recalc(&bk.grid[0], grid->width(), grid->height(), &bk.controlpoints[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BoneGridInterpolator::updateGridAndBone(BoneKeyframe& bk, Bone *bone)
|
void BoneGridInterpolator::updateGridAndBone(BoneKeyframe& bk, Bone *bone)
|
||||||
{
|
{
|
||||||
updateGridOnly(bk, bone);
|
updateGridOnly(bk, bone);
|
||||||
Vector *dst = bone->getDrawGrid().data();
|
Vector *dst = bone->getGrid()->data();
|
||||||
std::copy(bk.grid.begin(), bk.grid.end(), dst);
|
std::copy(bk.grid.begin(), bk.grid.end(), dst);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "SplineGrid.h"
|
#include "SplineGrid.h"
|
||||||
#include "RenderBase.h"
|
#include "RenderBase.h"
|
||||||
#include "Core.h"
|
#include "Core.h"
|
||||||
|
#include "RenderGrid.h"
|
||||||
|
|
||||||
SplineGridCtrlPoint *SplineGridCtrlPoint::movingPoint;
|
SplineGridCtrlPoint *SplineGridCtrlPoint::movingPoint;
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ void SplineGridCtrlPoint::onUpdate(float dt)
|
||||||
}
|
}
|
||||||
|
|
||||||
SplineGrid::SplineGrid()
|
SplineGrid::SplineGrid()
|
||||||
: deg(0)
|
: wasModified(false), deg(0)
|
||||||
{
|
{
|
||||||
setWidthHeight(128, 128);
|
setWidthHeight(128, 128);
|
||||||
renderQuad = true;
|
renderQuad = true;
|
||||||
|
@ -80,12 +81,12 @@ SplineGrid::~SplineGrid()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned degx, unsigned degy)
|
RenderGrid *SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned degx, unsigned degy)
|
||||||
{
|
{
|
||||||
size_t oldcpx = bsp.ctrlX();
|
size_t oldcpx = bsp.ctrlX();
|
||||||
size_t oldcpy = bsp.ctrlY();
|
size_t oldcpy = bsp.ctrlY();
|
||||||
|
|
||||||
this->createGrid(xres, yres);
|
RenderGrid *ret = this->createGrid(xres, yres);
|
||||||
|
|
||||||
std::vector<SplineGridCtrlPoint*> oldp;
|
std::vector<SplineGridCtrlPoint*> oldp;
|
||||||
ctrlp.swap(oldp);
|
ctrlp.swap(oldp);
|
||||||
|
@ -121,13 +122,18 @@ void SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned d
|
||||||
}
|
}
|
||||||
|
|
||||||
recalc();
|
recalc();
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplineGrid::recalc()
|
void SplineGrid::recalc()
|
||||||
{
|
{
|
||||||
exportControlPoints(&bsp.controlpoints[0]);
|
exportControlPoints(&bsp.controlpoints[0]);
|
||||||
bsp.recalc(drawGrid.data(), drawGrid.width(), drawGrid.height());
|
if(grid)
|
||||||
wasModified = true;
|
{
|
||||||
|
bsp.recalc(grid->data(), grid->width(), grid->height());
|
||||||
|
wasModified = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplineGrid::exportControlPoints(Vector* controlpoints)
|
void SplineGrid::exportControlPoints(Vector* controlpoints)
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
~SplineGrid();
|
~SplineGrid();
|
||||||
|
|
||||||
// # of control points on each axis
|
// # of control points on each axis
|
||||||
void resize(size_t w, size_t h, size_t xres, size_t yres, unsigned degx, unsigned degy);
|
RenderGrid *resize(size_t w, size_t h, size_t xres, size_t yres, unsigned degx, unsigned degy);
|
||||||
void recalc();
|
void recalc();
|
||||||
void exportControlPoints(Vector *controlpoints);
|
void exportControlPoints(Vector *controlpoints);
|
||||||
void importControlPoints(const Vector *controlpoints);
|
void importControlPoints(const Vector *controlpoints);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue