diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 9c3a80d..84011d2 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "RenderBase.h" #include "Game.h" #include "SplineGrid.h" +#include "RenderGrid.h" int TIMELINE_GRIDSIZE = 10; @@ -958,8 +959,9 @@ void AnimationEditor::editStripKey() } else { - if(editingBone && !editingBone->getDrawGrid().empty()) + if(editingBone && editingBone->getGrid()) { + RenderGrid *grid = editingBone->getGrid(); Animation *a = editSprite->getCurrentAnimation(); BoneGridInterpolator *interp = a->getBoneGridInterpolator(editingBone->boneIdx); @@ -973,12 +975,12 @@ void AnimationEditor::editStripKey() assert(bk->controlpoints.size() == interp->bsp.ctrlX() * interp->bsp.ctrlY()); 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->setWidthHeight(editingBone->width, editingBone->height); splinegrid->position = Vector(400, 300); //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]); //editSprite->addChild(splinegrid, PM_STATIC, RBP_OFF, CHILD_FRONT); //editSprite->alphaMod = 0.5f; diff --git a/Aquaria/Element.cpp b/Aquaria/Element.cpp index fc7f28d..b348a3f 100644 --- a/Aquaria/Element.cpp +++ b/Aquaria/Element.cpp @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Element.h" #include "Game.h" +#include "RenderGrid.h" ElementEffectData::ElementEffectData() : elementEffectType(EFX_NONE) @@ -182,8 +183,8 @@ void Element::update(float dt) updateLife(dt); if (eff) updateEffects(dt); - if (!drawGrid.empty()) - updateGrid(dt); + if(grid) + grid->update(dt); } } @@ -204,26 +205,8 @@ int Element::getElementEffectIndex() void Element::setGridFromWavy() { - if (!drawGrid.empty()) - { - 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; - } - } - } - } + if(grid && eff->wavy.size()) + grid->setFromWavy(&eff->wavy[0], eff->wavy.size(), width); } void Element::setElementEffectByIndex(int eidx) diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 18ad3fd..6b2d13b 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Gradient.h" #include "TTFFont.h" #include "RoundedRect.h" +#include "RenderGrid.h" #define GEM_GRAB 10 @@ -561,8 +562,12 @@ void WorldMapRender::setVis(WorldMapTile *tile) if (visMethod == VIS_VERTEX) { - tile->q->setSegs(MAPVIS_SUBDIV, MAPVIS_SUBDIV, 0, 0, 0, 0, 2.0, 1); - tileDataToVis(tile, tile->q->getDrawGrid()); + RenderGrid *g = tile->q->setSegs(MAPVIS_SUBDIV, MAPVIS_SUBDIV, 0, 0, 0, 0, 2.0, 1); + if(g) + { + g->drawOrder = GRID_DRAW_WORLDMAP; + tileDataToVis(tile, g->array2d()); + } } else if (visMethod == VIS_WRITE) { @@ -662,7 +667,6 @@ WorldMapRender::WorldMapRender() : RenderObject(), ActionMapper() q->setTexturePointer(texs[i]); q->position = pos; q->alphaMod = 0; - q->drawOrder = Quad::GRID_DRAW_WORLDMAP; tile->q = q; diff --git a/BBGE/AfterEffect.h b/BBGE/AfterEffect.h index 3a0e70c..9a9855b 100644 --- a/BBGE/AfterEffect.h +++ b/BBGE/AfterEffect.h @@ -112,7 +112,7 @@ public: int screenWidth, screenHeight; int textureWidth, textureHeight; - Vector ** drawGrid; + Vector ** drawGrid; // TODO: make this + related code use RenderGrid // returns handle > 0 on success int loadShaderFile(const char *vert, const char *frag); diff --git a/BBGE/CMakeLists.txt b/BBGE/CMakeLists.txt index 39a1372..97b273c 100644 --- a/BBGE/CMakeLists.txt +++ b/BBGE/CMakeLists.txt @@ -72,6 +72,8 @@ set(BBGE_SRCS Refcounted.h RenderBase.cpp RenderBase.h + RenderGrid.cpp + RenderGrid.h RenderObject.cpp RenderObject.h RenderObject_inline.h diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index 5d67bef..1a3ab79 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -21,148 +21,92 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Quad.h" #include "Core.h" #include "RenderBase.h" +#include "RenderGrid.h" #include Quad::Quad(const std::string &tex, const Vector &pos) : RenderObject() { - renderBorderColor = Vector(1,1,1); initQuad(); + renderBorderColor = Vector(1,1,1); position = pos; setTexture(tex); } +Quad::Quad() : RenderObject() +{ + initQuad(); +} - -void Quad::setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo) +Quad::~Quad() { 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) +void Quad::initQuad() { - drawGrid.init(xd, yd); - resetGrid(); - Vector *dg = drawGrid.data(); - for(size_t i = 0; i < drawGrid.linearsize(); ++i) - dg[i].z = 1.0f; + addType(SCO_QUAD); + borderAlpha = 0.5; + repeatToFillScale = Vector(1,1); + + autoWidth = autoHeight = 0; + + renderBorder = false; + renderCenter = true; + width = 2; height = 2; + + upperLeftTextureCoordinates = Vector(0,0); + lowerRightTextureCoordinates = Vector(1,1); + renderQuad = true; + grid = NULL; } -void Quad::setDrawGridAlpha(size_t x, size_t y, float alpha) +void Quad::deleteGrid() { - if (x < drawGrid.width() && y < drawGrid.height()) - { - drawGrid(x, y).z = alpha; - } + delete grid; + grid = NULL; } -void Quad::setStripPoints(bool vert, const Vector *points, size_t n) +void Quad::destroy() { - if (drawGrid.empty()) return; - resetGrid(); + deleteGrid(); + RenderObject::destroy(); +} - 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) +RenderGrid *Quad::setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, float dgtm, bool dgo) { - 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; - } - } + RenderGrid *g = createGrid(x, y); + if(g) + g->setSegs(dgox, dgoy, dgmx, dgmy, dgtm, dgo); + return g; } -void Quad::ResetGridAndAlpha(Vector* dst, size_t w, size_t h, float alpha) +RenderGrid *Quad::createGrid(int xd, int yd) { - 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; - } - } + delete grid; + return (grid = xd && yd + ? new RenderGrid(xd, yd) + : NULL); } -void Quad::resetGrid() +void Quad::setDrawGridAlpha(size_t x, size_t y, float alpha) { - if (drawGrid.empty()) return; - - ResetGrid(drawGrid.data(), drawGrid.width(), drawGrid.height()); + if(grid) + grid->setAlpha(x, y, alpha); } -void Quad::initQuad() +void Quad::setStripPoints(bool vert, const Vector *points, size_t n) { - repeatToFillScale = Vector(1,1); - gridType = GRID_WAVY; - gridTimer = 0; - - doUpdateGrid = false; - - autoWidth = autoHeight = 0; - - renderBorder = false; - renderCenter = true; - width = 2; height = 2; - - - - upperLeftTextureCoordinates = Vector(0,0); - lowerRightTextureCoordinates = Vector(1,1); - renderQuad = true; + 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 @@ -195,27 +139,7 @@ void Quad::_renderBorder(const RenderState& rs, Vector color, float borderalpha) 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 { @@ -275,272 +199,28 @@ bool Quad::isCoordinateInsideWorldRect(const Vector &coord, int w, int h) const 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 { - if (drawGrid.width() < 2 || drawGrid.height() < 2) - return; - - switch(drawOrder) - { - case GRID_DRAW_LRTB: - renderGrid_LRTB(rs); - break; + RenderState rx(rs); + rx.color = rs.color * this->color; + rx.alpha = rs.alpha * this->alpha.x * this->alphaMod; - case GRID_DRAW_LRBT: - renderGrid_LRBT(rs); - break; + glPushMatrix(); + glScalef(width, height, 1); - case GRID_DRAW_WORLDMAP: - renderGridWithAlpha(rs); - break; - } + grid->render(rx, upperLeftTextureCoordinates, lowerRightTextureCoordinates); // debug points 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); - glPointSize(2); - 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(); + grid->renderDebugPoints(rx); RenderObject::lastTextureApplied = 0; } -} - -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(); + glPopMatrix(); } -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) { @@ -556,7 +236,7 @@ void Quad::onRender(const RenderState& rs) const const float _w2 = width*0.5f; const float _h2 = height*0.5f; - if (drawGrid.empty()) + if (!grid) { glBegin(GL_QUADS); { @@ -643,9 +323,9 @@ void Quad::onUpdate(float dt) else if (autoHeight == AUTO_VIRTUALHEIGHT) height = core->getVirtualHeight(); - if (!drawGrid.empty() && alpha.x > 0 && alphaMod > 0) + if (grid && alpha.x > 0 && alphaMod > 0) { - updateGrid(dt); + grid->update(dt); } } diff --git a/BBGE/Quad.h b/BBGE/Quad.h index 0fcfa37..1670987 100644 --- a/BBGE/Quad.h +++ b/BBGE/Quad.h @@ -39,12 +39,15 @@ protected: void onRender(const RenderState& rs) const OVERRIDE; }; +class RenderGrid; + class Quad : public RenderObject { public: Quad(const std::string &tex, const Vector &pos); Quad(); - void createGrid(int x, int y); + virtual ~Quad(); + RenderGrid *createGrid(int x, int y); void destroy() OVERRIDE; bool isCoordinateInside(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 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 repeatTextureToFill(bool on); void refreshRepeatTextureToFill(); bool isRepeatingTextureToFill() const { return repeatTexture; } void setStripPoints(bool vert, const Vector *points, size_t n); - Array2d& getDrawGrid() { return drawGrid; } - const Array2d& getDrawGrid() const { return drawGrid; } + RenderGrid *getGrid() { return grid; } + const RenderGrid *getGrid() const { return grid; } void reloadDevice() OVERRIDE; void deleteGrid(); - Vector upperLeftTextureCoordinates, lowerRightTextureCoordinates; - 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_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 - + // TODO: this should be a bitmask + char autoWidth, autoHeight; bool renderQuad, renderCenter, renderBorder; + Vector texOff; float borderAlpha; Vector renderBorderColor; 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: + RenderGrid *grid; -protected: - float gridTimer; - Array2d drawGrid; void resetGrid(); - void updateGrid(float dt); 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 onRender(const RenderState& rs) const OVERRIDE; void onUpdate(float dt) OVERRIDE; -public: - GridDrawOrder drawOrder; private: - bool doUpdateGrid; void initQuad(); void _renderBorder(const RenderState& rs, Vector color, float borderalpha) const; }; diff --git a/BBGE/RenderGrid.cpp b/BBGE/RenderGrid.cpp new file mode 100644 index 0000000..b1b44d0 --- /dev/null +++ b/BBGE/RenderGrid.cpp @@ -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(); +} + diff --git a/BBGE/RenderGrid.h b/BBGE/RenderGrid.h new file mode 100644 index 0000000..c8a4169 --- /dev/null +++ b/BBGE/RenderGrid.h @@ -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& array2d() { return grid; } + const Array2d& array2d() const { return grid; } + + static void ResetWithAlpha(Vector* dst, size_t w, size_t h, float alpha); + +protected: + Array2d 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 + + diff --git a/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index 6f770fa..7a6e70e 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "ReadXML.h" #include "RenderBase.h" #include "SplineGrid.h" +#include "RenderGrid.h" #include using namespace tinyxml2; @@ -129,16 +130,9 @@ void Bone::addSegment(Bone *b) void Bone::createStrip(bool vert, int num) { - if (!vert) - { - createGrid(num, 2); - } - else - { - createGrid(2, num); - } + RenderGrid *grid = vert ? createGrid(2, num) : createGrid(num, 2); stripVert = vert; - gridType = GRID_STRIP; + grid->gridType = GRID_STRIP; changeStrip.resize(num); } @@ -980,6 +974,7 @@ bool SkeletalSprite::saveSkeletal(const std::string &fn) XMLElement *bones = xml->NewElement("Bones"); for (i = 0; i < this->bones.size(); i++) { + const RenderGrid * const grid = this->bones[i]->getGrid(); XMLElement *bone = xml->NewElement("Bone"); bone->SetAttribute("idx", (unsigned int) this->bones[i]->boneIdx); 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); if (!this->bones[i]->prt.empty()) 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; - os << this->bones[i]->getDrawGrid().width() << " " << this->bones[i]->getDrawGrid().height(); + os << grid->width() << " " << grid->height(); bone->SetAttribute("grid", os.str().c_str()); } 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; 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); if(bone) { + const RenderGrid * const bgrid = bone->getGrid(); os << b->idx << " " << b->x << " " << b->y << " " << b->rot << " "; // 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 << " "; if(usedGridSize) for (size_t i = 0; i < usedGridSize; i++) @@ -1604,12 +1601,13 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) } if (bone->Attribute("grid")) { - if(newb->getDrawGrid().empty()) + RenderGrid *grid = newb->getGrid(); + if(!grid) { SimpleIStringStream is(bone->Attribute("grid"), SimpleIStringStream::REUSE); int x, y; is >> x >> y; - newb->createGrid(x, y); + grid = newb->createGrid(x, y); } else { @@ -1617,11 +1615,11 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) os << "Bone idx " << newb->idx << " already has a DrawGrid, ignoring \"grid\" attribute"; errorLog(os.str()); } - } - if(const char *gdo = bone->Attribute("gridDrawOrder")) - { - int ord = atoi(gdo); - newb->drawOrder = (Quad::GridDrawOrder)ord; + if(const char *gdo = bone->Attribute("gridDrawOrder")) + { + int ord = atoi(gdo); + grid->drawOrder = (GridDrawOrder)ord; + } } 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++) { Bone *bone = this->bones[i]; - const Array2d& dg = bone->getDrawGrid(); BoneKeyframe *bk = newSkeletalKeyframe.getBoneKeyframe(bone->boneIdx); if(!bk) { @@ -1845,7 +1842,8 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) debugLog(os.str()); continue; } - if(bi->getDrawGrid().empty()) + RenderGrid *grid = bi->getGrid(); + if(!grid) { std::ostringstream os; 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; - 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")) { 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 earlier const char *idata = interp->Attribute("data"); @@ -1898,7 +1896,7 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) bgip.bsp.resize(cx, cy, degx, degy); 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 ..." // ^- 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.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()) bkey2->grid.resize(b->changeStrip.size()); @@ -2074,22 +2073,21 @@ void AnimationLayer::updateBones() } 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& dg = b->getDrawGrid(); - const size_t N = dg.linearsize(); + const size_t N = grid->linearsize(); if(bkey1->grid.size() < 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) { 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) { 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) { - const Array2d& dg = bone->getDrawGrid(); + const RenderGrid *grid = bone->getGrid(); assert(bone->boneIdx == bk.idx); - assert(bk.grid.size() == dg.linearsize()); - bsp.recalc(&bk.grid[0], dg.width(), dg.height(), &bk.controlpoints[0]); + assert(bk.grid.size() == grid->linearsize()); + bsp.recalc(&bk.grid[0], grid->width(), grid->height(), &bk.controlpoints[0]); } void BoneGridInterpolator::updateGridAndBone(BoneKeyframe& bk, Bone *bone) { updateGridOnly(bk, bone); - Vector *dst = bone->getDrawGrid().data(); + Vector *dst = bone->getGrid()->data(); std::copy(bk.grid.begin(), bk.grid.end(), dst); } diff --git a/BBGE/SplineGrid.cpp b/BBGE/SplineGrid.cpp index 42d9d9c..6a1e89e 100644 --- a/BBGE/SplineGrid.cpp +++ b/BBGE/SplineGrid.cpp @@ -1,6 +1,7 @@ #include "SplineGrid.h" #include "RenderBase.h" #include "Core.h" +#include "RenderGrid.h" SplineGridCtrlPoint *SplineGridCtrlPoint::movingPoint; @@ -69,7 +70,7 @@ void SplineGridCtrlPoint::onUpdate(float dt) } SplineGrid::SplineGrid() - : deg(0) + : wasModified(false), deg(0) { setWidthHeight(128, 128); 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 oldcpy = bsp.ctrlY(); - this->createGrid(xres, yres); + RenderGrid *ret = this->createGrid(xres, yres); std::vector 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(); + + return ret; } void SplineGrid::recalc() { exportControlPoints(&bsp.controlpoints[0]); - bsp.recalc(drawGrid.data(), drawGrid.width(), drawGrid.height()); - wasModified = true; + if(grid) + { + bsp.recalc(grid->data(), grid->width(), grid->height()); + wasModified = true; + } } void SplineGrid::exportControlPoints(Vector* controlpoints) diff --git a/BBGE/SplineGrid.h b/BBGE/SplineGrid.h index 4f7d9eb..962e824 100644 --- a/BBGE/SplineGrid.h +++ b/BBGE/SplineGrid.h @@ -33,7 +33,7 @@ public: ~SplineGrid(); // # 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 exportControlPoints(Vector *controlpoints); void importControlPoints(const Vector *controlpoints);