From 58e9ba340e053e8c751231a54578a28bfc6596f2 Mon Sep 17 00:00:00 2001 From: fgenesis Date: Sun, 25 Sep 2022 04:30:38 +0200 Subject: [PATCH] Add skel/bone gridDrawOrder attrib to control the way the gris is drawn Also ignore grid.z (used as worldmap alpha) by default because it's really only needed for the world map and ignoring it results in less GL calls. --- Aquaria/AnimationEditor.cpp | 1 + Aquaria/WorldMapRender.cpp | 1 + BBGE/Quad.cpp | 188 +++++++++++++++++++++++++++++++----- BBGE/Quad.h | 14 ++- BBGE/SkeletalSprite.cpp | 9 ++ 5 files changed, 189 insertions(+), 24 deletions(-) diff --git a/Aquaria/AnimationEditor.cpp b/Aquaria/AnimationEditor.cpp index 1a180e3..4a1ab95 100644 --- a/Aquaria/AnimationEditor.cpp +++ b/Aquaria/AnimationEditor.cpp @@ -971,6 +971,7 @@ void AnimationEditor::editStripKey() assert(bk->controlpoints.size() == interp->bsp.ctrlX() * interp->bsp.ctrlY()); splinegrid = new SplineGrid; + splinegrid->drawOrder = editingBone->drawOrder; splinegrid->setTexture(editingBone->texture->name); splinegrid->setWidthHeight(editingBone->width, editingBone->height); splinegrid->position = Vector(400, 300); diff --git a/Aquaria/WorldMapRender.cpp b/Aquaria/WorldMapRender.cpp index f92af90..0c065b6 100644 --- a/Aquaria/WorldMapRender.cpp +++ b/Aquaria/WorldMapRender.cpp @@ -659,6 +659,7 @@ WorldMapRender::WorldMapRender() : RenderObject(), ActionMapper() q->setTexture(tn); q->position = pos; q->alphaMod = 0; + q->drawOrder = Quad::GRID_DRAW_WORLDMAP; tile->q = q; diff --git a/BBGE/Quad.cpp b/BBGE/Quad.cpp index 8c46837..01a038a 100644 --- a/BBGE/Quad.cpp +++ b/BBGE/Quad.cpp @@ -199,6 +199,7 @@ Quad::Quad() : RenderObject() { addType(SCO_QUAD); borderAlpha = 0.5; + drawOrder = GRID_DRAW_DEFAULT; initQuad(); @@ -311,6 +312,170 @@ 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; + + case GRID_DRAW_LRBT: + renderGrid_LRBT(rs); + break; + + case GRID_DRAW_WORLDMAP: + renderGridWithAlpha(rs); + break; + } + + // 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(); + if (texture) + glBindTexture(GL_TEXTURE_2D, texture->textures[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(); +} + +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); @@ -339,7 +504,6 @@ void Quad::renderGrid(const RenderState& rs) const 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; @@ -377,28 +541,6 @@ void Quad::renderGrid(const RenderState& rs) const } } glEnd(); - - // debug points - if (RenderObject::renderCollisionShape) - { - 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(); - if (texture) - glBindTexture(GL_TEXTURE_2D, texture->textures[0]); - } } void Quad::repeatTextureToFill(bool on) diff --git a/BBGE/Quad.h b/BBGE/Quad.h index 1b4f760..2221fce 100644 --- a/BBGE/Quad.h +++ b/BBGE/Quad.h @@ -74,7 +74,14 @@ public: InterpolatedVector 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 { @@ -104,7 +111,9 @@ protected: 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; @@ -116,6 +125,9 @@ protected: void onSetTexture(); void onRender(const RenderState& rs) const OVERRIDE; void onUpdate(float dt); + +public: + GridDrawOrder drawOrder; private: bool doUpdateGrid; void initQuad(); diff --git a/BBGE/SkeletalSprite.cpp b/BBGE/SkeletalSprite.cpp index 74ae607..f15d916 100644 --- a/BBGE/SkeletalSprite.cpp +++ b/BBGE/SkeletalSprite.cpp @@ -1053,6 +1053,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) + { + bone->SetAttribute("gridDrawOrder", (int)this->bones[i]->drawOrder); + } for (Children::iterator j = this->bones[i]->children.begin(); j != this->bones[i]->children.end(); j++) @@ -1619,6 +1623,11 @@ void SkeletalSprite::loadSkeletal(const std::string &fn) errorLog(os.str()); } } + if(const char *gdo = bone->Attribute("gridDrawOrder")) + { + int ord = atoi(gdo); + newb->drawOrder = (Quad::GridDrawOrder)ord; + } bone = bone->NextSiblingElement("Bone"); } // attach bones