From 8e979e0e05686930e52f216ed0af9256d2e91371 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Wed, 14 Sep 2022 05:11:56 +0200 Subject: [PATCH] simplify Quad::drawGrid --- Aquaria/Element.cpp | 27 +++--- Aquaria/WorldMapRender.cpp | 23 ++--- BBGE/DataStructures.h | 12 ++- BBGE/Quad.cpp | 169 +++++++++++++++---------------------- BBGE/Quad.h | 9 +- BBGE/SkeletalSprite.cpp | 2 +- BBGE/SplineGrid.cpp | 13 +-- BBGE/SplineGrid.h | 2 - 8 files changed, 109 insertions(+), 148 deletions(-) diff --git a/Aquaria/Element.cpp b/Aquaria/Element.cpp index ac1e33d..5122e90 100644 --- a/Aquaria/Element.cpp +++ b/Aquaria/Element.cpp @@ -182,7 +182,7 @@ void Element::update(float dt) updateLife(dt); if (eff) updateEffects(dt); - if (drawGrid) + if (!drawGrid.empty()) updateGrid(dt); } } @@ -204,29 +204,26 @@ int Element::getElementEffectIndex() void Element::setGridFromWavy() { - if (drawGrid) + if (!drawGrid.empty()) { + const size_t NX = drawGrid.width() - 1; + const size_t H = drawGrid.height(); - const float w = float(getWidth()); - for (size_t x = 0; x < xDivs-1; x++) + const float iw = 1.0f / float(getWidth()); + for (size_t x = 0; x < NX; x++) { - for (size_t y = 0; y < yDivs; y++) + for (size_t y = 0; y < H; y++) { - const int wavy_y = (yDivs - y)-1; - const float tmp = eff->wavy[wavy_y].x / w; - if (wavy_y < 0 || (size_t) wavy_y < eff->wavy.size()) + const size_t wavy_y = (H - y)-1; + if (wavy_y < 0 || wavy_y < eff->wavy.size()) { - - drawGrid[x][y].x = tmp - 0.5f; - drawGrid[x+1][y].x = tmp + 0.5f; + const float tmp = eff->wavy[wavy_y].x * iw; + drawGrid(x,y).x = tmp - 0.5f; + drawGrid(x+1,y).x = tmp + 0.5f; } } } } - else - { - //std::cout << "no drawgrid...\n"; - } } void Element::setElementEffectByIndex(int eidx) diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index 5228089..f92af90 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -443,22 +443,22 @@ void WorldMapRender::setProperTileColor(WorldMapTile *tile) } -static void tileDataToVis(WorldMapTile *tile, Vector **vis) +static void tileDataToVis(WorldMapTile *tile, Array2d& vis) { const unsigned char *data = tile->getData(); if (data != 0) { const float a = tile->prerevealed ? 0.4f : baseMapSegAlpha; - const unsigned int rowSize = MAPVIS_SUBDIV/8; - for (unsigned int y = 0; y < MAPVIS_SUBDIV; y++, data += rowSize) + const size_t rowSize = MAPVIS_SUBDIV/8; + for (size_t y = 0; y < MAPVIS_SUBDIV; y++, data += rowSize) { - for (unsigned int x = 0; x < MAPVIS_SUBDIV; x += 8) + for (size_t x = 0; x < MAPVIS_SUBDIV; x += 8) { unsigned char dataByte = data[x/8]; - for (unsigned int x2 = 0; x2 < 8; x2++) + for (size_t x2 = 0; x2 < 8; x2++) { - vis[x+x2][y].z = (dataByte & (1 << x2)) ? visibleMapSegAlpha : a; + vis(x+x2,y).z = (dataByte & (1 << x2)) ? visibleMapSegAlpha : a; } } } @@ -466,14 +466,9 @@ static void tileDataToVis(WorldMapTile *tile, Vector **vis) else { const float a = tile->prerevealed ? 0.4f : baseMapSegAlpha; - for (int x = 0; x < MAPVIS_SUBDIV; x++) - { - for (int y = 0; y < MAPVIS_SUBDIV; y++) - { - vis[x][y].z = a; - } - } - return; + Vector *gp = vis.data(); + for(size_t i = 0; i < vis.linearsize(); ++i) + gp[i].z = a; } } diff --git a/BBGE/DataStructures.h b/BBGE/DataStructures.h index a874b0d..d257a55 100644 --- a/BBGE/DataStructures.h +++ b/BBGE/DataStructures.h @@ -10,8 +10,8 @@ template class Array2d { protected: - size_t _w, _h; std::vector _v; + size_t _w, _h; public: Array2d() : _w(0), _h(0) {} @@ -32,6 +32,16 @@ public: _v.clear(); } + bool empty() const + { + return _v.empty(); + } + + size_t linearsize() const + { + return _v.size(); + } + void fill(const T& v) { std::fill(_v.begin(), _v.end(), v); diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index b6b8913..a5ec506 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -40,101 +40,79 @@ void Quad::setSegs(int x, int y, float dgox, float dgoy, float dgmx, float dgmy, deleteGrid(); if (x == 0 || y == 0) { - gridTimer = 0; - xDivs = 0; - yDivs = 0; doUpdateGrid = false; } else { + doUpdateGrid = true; this->drawGridOffsetX = dgox; this->drawGridOffsetY = dgoy; this->drawGridModX = dgmx; this->drawGridModY = dgmy; this->drawGridTimeMultiplier = dgtm; drawGridOut = dgo; - xDivs = x; - yDivs = y; - createGrid(x, y); - - gridTimer = 0; - - doUpdateGrid = true; } + + gridTimer = 0; } void Quad::createGrid(int xd, int yd) { - deleteGrid(); - - xDivs = xd; - yDivs = yd; - - drawGrid = new Vector * [xDivs]; - for (size_t i = 0; i < xDivs; i++) - { - drawGrid[i] = new Vector [yDivs]; - for (size_t j = 0; j < yDivs; j++) - { - drawGrid[i][j].z = 1; - } - } - + 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 < xDivs && y < yDivs) + if (x < drawGrid.width() && y < drawGrid.height()) { - drawGrid[x][y].z = alpha; + drawGrid(x, y).z = alpha; } } -void Quad::setGridPoints(bool vert, const std::vector &points) +void Quad::setStripPoints(bool vert, const Vector *points, size_t n) { - if (!drawGrid) return; + if (drawGrid.empty()) return; resetGrid(); - for (size_t i = 0; i < points.size(); i++) + + const float mul = float(n); + + if (!vert) // horz { - if (!vert) // horz + const size_t xmax = std::min(drawGrid.width(), n); + for (size_t y = 0; y < drawGrid.height(); y++) { - for (size_t y = 0; y < yDivs; y++) - { - for (size_t x = 0; x < xDivs; x++) - { - if (x < points.size()) - { - drawGrid[x][y] += points[x]; - } - } - } - } - else - { - for (size_t x = 0; x < xDivs; x++) - { - for (size_t y = 0; y < yDivs; y++) - { - if (y < points.size()) - { - drawGrid[x][y] += points[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() { - for (size_t i = 0; i < xDivs; i++) + const float yMulF = 1.0f / (float)(drawGrid.height()-1); + const float xMulF = 1.0f / (float)(drawGrid.width()-1); + + for (size_t y = 0; y < drawGrid.height(); y++) { - for (size_t j = 0; j < yDivs; j++) + Vector *row = drawGrid.row(y); + const float yval = float(y)*yMulF-0.5f; + for (size_t x = 0; x < drawGrid.width(); x++) { - drawGrid[i][j].x = i/(float)(xDivs-1)-0.5f; - drawGrid[i][j].y = j/(float)(yDivs-1)-0.5f; + row[x].x = float(x)*xMulF-0.5f; + row[x].y = yval; } } } @@ -144,15 +122,11 @@ void Quad::initQuad() repeatToFillScale = Vector(1,1); gridType = GRID_WAVY; gridTimer = 0; - xDivs = 0; - yDivs = 0; doUpdateGrid = false; autoWidth = autoHeight = 0; - drawGrid = 0; - renderBorder = false; renderCenter = true; width = 2; height = 2; @@ -177,15 +151,7 @@ Quad::Quad() : RenderObject() void Quad::deleteGrid() { - if (drawGrid) - { - for (size_t i = 0; i < xDivs; i++) - { - delete[] drawGrid[i]; - } - delete[] drawGrid; - drawGrid = 0; - } + drawGrid.clear(); } void Quad::destroy() @@ -254,32 +220,31 @@ bool Quad::isCoordinateInsideWorldRect(const Vector &coord, int w, int h) const void Quad::updateGrid(float dt) { - if (!doUpdateGrid) return; if (gridType == GRID_WAVY) { gridTimer += dt * drawGridTimeMultiplier; resetGrid(); - size_t hx = xDivs/2; - for (size_t x = 0; x < xDivs; x++) + 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 < yDivs; y++) + 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; + drawGrid(x,y).x += addX; else - drawGrid[x][y].x -= addX; + drawGrid(x,y).x -= addX; } - drawGrid[x][y].y += addY; + drawGrid(x,y).y += addY; } } } @@ -287,7 +252,7 @@ void Quad::updateGrid(float dt) void Quad::renderGrid(const RenderState& rs) const { - if (xDivs < 2 || yDivs < 2) + if (drawGrid.width() < 2 || drawGrid.height() < 2) return; const float percentX = fabsf(this->lowerRightTextureCoordinates.x - this->upperLeftTextureCoordinates.x); @@ -300,12 +265,15 @@ void Quad::renderGrid(const RenderState& rs) const (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)(xDivs-1); - const float incY = percentY / (float)(yDivs-1); + const float incX = percentX / float(NX); + const float incY = percentY / float(NY); const float w = this->getWidth(); const float h = this->getHeight(); @@ -319,38 +287,38 @@ void Quad::renderGrid(const RenderState& rs) const glBegin(GL_QUADS); float u0 = baseX; float u1 = u0 + incX; - for (size_t i = 0; i < (xDivs-1); i++, u0 = u1, u1 += incX) + for (size_t x = 0; x < NX; x++, u0 = u1, u1 += incX) { float v0 = 1 - percentY + baseY; float v1 = v0 + incY; - for (size_t j = 0; j < (yDivs-1); j++, v0 = v1, v1 += incY) + for (size_t y = 0; y < NY; y++, v0 = v1, v1 += incY) { - if (drawGrid[i][j].z != 0 || drawGrid[i][j+1].z != 0 || drawGrid[i+1][j].z != 0 || drawGrid[i+1][j+1].z != 0) + if (drawGrid(x,y).z != 0 || drawGrid(x,y+1).z != 0 || drawGrid(x+1,y).z != 0 || drawGrid(x+1,y+1).z != 0) { - glColor4f(red, green, blue, alpha*drawGrid[i][j].z); + glColor4f(red, green, blue, alpha*drawGrid(x,y).z); glTexCoord2f(u0, v0); - glVertex2f(w*drawGrid[i][j].x, h*drawGrid[i][j].y); + glVertex2f(w*drawGrid(x,y).x, h*drawGrid(x,y).y); - glColor4f(red, green, blue, alpha*drawGrid[i][j+1].z); + glColor4f(red, green, blue, alpha*drawGrid(x,y+1).z); glTexCoord2f(u0, v1); - glVertex2f(w*drawGrid[i][j+1].x, h*drawGrid[i][j+1].y); + glVertex2f(w*drawGrid(x,y+1).x, h*drawGrid(x,y+1).y); - glColor4f(red, green, blue, alpha*drawGrid[i+1][j+1].z); + glColor4f(red, green, blue, alpha*drawGrid(x+1,y+1).z); glTexCoord2f(u1, v1); - glVertex2f(w*drawGrid[i+1][j+1].x, h*drawGrid[i+1][j+1].y); + glVertex2f(w*drawGrid(x+1,y+1).x, h*drawGrid(x+1,y+1).y); - glColor4f(red, green, blue, alpha*drawGrid[i+1][j].z); + glColor4f(red, green, blue, alpha*drawGrid(x+1,y).z); glTexCoord2f(u1, v0); - glVertex2f(w*drawGrid[i+1][j].x, h*drawGrid[i+1][j].y); + glVertex2f(w*drawGrid(x+1,y).x, h*drawGrid(x+1,y).y); } } } @@ -363,15 +331,14 @@ void Quad::renderGrid(const RenderState& rs) const glPointSize(2); glColor3f(1,0,0); glBegin(GL_POINTS); - if(xDivs > 0 && yDivs > 0) - for (size_t i = 0; i < (xDivs-1); i++) + for (size_t x = 0; x < NX; x++) { - for (size_t j = 0; j < (yDivs-1); j++) + for (size_t y = 0; y < NY; y++) { - glVertex2f(w*drawGrid[i][j].x, h*drawGrid[i][j].y); - glVertex2f(w*drawGrid[i][j+1].x, h*drawGrid[i][j+1].y); - glVertex2f(w*drawGrid[i+1][j+1].x, h*drawGrid[i+1][j+1].y); - glVertex2f(w*drawGrid[i+1][j].x, h*drawGrid[i+1][j].y); + 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(); @@ -394,7 +361,7 @@ void Quad::onRender(const RenderState& rs) const const float _w2 = width*0.5f; const float _h2 = height*0.5f; - if (!drawGrid) + if (drawGrid.empty()) { glBegin(GL_QUADS); { @@ -511,7 +478,7 @@ void Quad::onUpdate(float dt) lowerRightTextureCoordinates.update(dt); upperLeftTextureCoordinates.update(dt); - if (drawGrid && alpha.x > 0 && alphaMod > 0) + if (!drawGrid.empty() && alpha.x > 0 && alphaMod > 0) { updateGrid(dt); } diff --git a/BBGE/Quad.h b/BBGE/Quad.h index 9baf55e..490dcc1 100644 --- a/BBGE/Quad.h +++ b/BBGE/Quad.h @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define BBGE_QUAD_H #include "RenderObject.h" +#include "DataStructures.h" class OutlineRect : public RenderObject { @@ -62,8 +63,9 @@ public: void repeatTextureToFill(bool on); void refreshRepeatTextureToFill(); bool isRepeatingTextureToFill() const { return repeatTexture; } - void setGridPoints(bool vert, const std::vector& points); - Vector ** getDrawGrid() { return drawGrid; } + void setStripPoints(bool vert, const Vector *points, size_t n); + Array2d& getDrawGrid() { return drawGrid; } + const Array2d& getDrawGrid() const { return drawGrid; } void reloadDevice(); @@ -93,8 +95,7 @@ public: protected: float gridTimer; - size_t xDivs, yDivs; - Vector ** drawGrid; + Array2d drawGrid; void resetGrid(); void updateGrid(float dt); diff --git a/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index ad56016..6015243 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -1923,7 +1923,7 @@ void AnimationLayer::updateBones() { b->changeStrip[i] = Vector(lerp(bkey1->grid[i].x, bkey2->grid[i].x, dt, lerpType), lerp(bkey1->grid[i].y, bkey2->grid[i].y, dt, lerpType)); } - b->setGridPoints(b->stripVert, b->changeStrip); + b->setStripPoints(b->stripVert, &b->changeStrip[0], b->changeStrip.size()); } } } diff --git a/BBGE/SplineGrid.cpp b/BBGE/SplineGrid.cpp index a0538ae..59b2708 100644 --- a/BBGE/SplineGrid.cpp +++ b/BBGE/SplineGrid.cpp @@ -39,7 +39,7 @@ void SplineGridCtrlPoint::onUpdate(float dt) } SplineGrid::SplineGrid() - : _xres(0), _yres(0) + : deg(0) { setWidthHeight(128, 128); renderQuad = true; @@ -56,7 +56,6 @@ void SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned d size_t oldcpy = bsp.ctrlY(); this->createGrid(xres, yres); - gridpoints.resize(xres * yres); std::vector oldp; ctrlp.swap(oldp); @@ -75,8 +74,6 @@ void SplineGrid::resize(size_t w, size_t h, size_t xres, size_t yres, unsigned d } } - _xres = xres; - _yres = yres; bsp.resize(w, h, deg, deg, -1.0f, 1.0f); // kill any excess points @@ -100,12 +97,8 @@ void SplineGrid::recalc() { for(size_t i = 0; i < ctrlp.size(); ++i) bsp.controlpoints[i] = ctrlp[i]->getSplinePosition(); - Vector *gp = &gridpoints[0]; - bsp.recalc(gp, _xres, _yres); - Vector **dg = this->getDrawGrid(); - for(size_t y = 0; y < _yres; ++y) - for(size_t x = 0; x < _xres; ++x) - dg[x][y] = *gp++; + bsp.recalc(drawGrid.data(), drawGrid.width(), drawGrid.height()); + } diff --git a/BBGE/SplineGrid.h b/BBGE/SplineGrid.h index d2a8e82..cc1cc8e 100644 --- a/BBGE/SplineGrid.h +++ b/BBGE/SplineGrid.h @@ -45,8 +45,6 @@ private: SplineGridCtrlPoint *createControlPoint(size_t x, size_t y); std::vector ctrlp; - std::vector gridpoints; - size_t _xres, _yres; unsigned deg; BSpline2D bsp; };