mirror of https://github.com/axmolengine/axmol.git
Slice9 Sprite with triangles, not quads (#17105)
* sprites: use triangles instead of quads uses less memory * oops, color should be white by default * works with flipped sprites * none for xcode
This commit is contained in:
parent
93d193dfcc
commit
ff8e622b7a
|
@ -313,7 +313,8 @@ Sprite::Sprite(void)
|
||||||
, _insideBounds(true)
|
, _insideBounds(true)
|
||||||
, _centerRectNormalized(0,0,1,1)
|
, _centerRectNormalized(0,0,1,1)
|
||||||
, _numberOfSlices(1)
|
, _numberOfSlices(1)
|
||||||
, _quads(nullptr)
|
, _trianglesVertex(nullptr)
|
||||||
|
, _trianglesIndex(nullptr)
|
||||||
, _strechFactor(Vec2::ONE)
|
, _strechFactor(Vec2::ONE)
|
||||||
, _originalContentSize(Size::ZERO)
|
, _originalContentSize(Size::ZERO)
|
||||||
, _strechEnabled(true)
|
, _strechEnabled(true)
|
||||||
|
@ -326,7 +327,8 @@ Sprite::Sprite(void)
|
||||||
|
|
||||||
Sprite::~Sprite()
|
Sprite::~Sprite()
|
||||||
{
|
{
|
||||||
CC_SAFE_FREE(_quads);
|
CC_SAFE_FREE(_trianglesVertex);
|
||||||
|
CC_SAFE_FREE(_trianglesIndex);
|
||||||
CC_SAFE_RELEASE(_spriteFrame);
|
CC_SAFE_RELEASE(_spriteFrame);
|
||||||
CC_SAFE_RELEASE(_texture);
|
CC_SAFE_RELEASE(_texture);
|
||||||
}
|
}
|
||||||
|
@ -438,7 +440,6 @@ void Sprite::updatePoly()
|
||||||
// C) 9-sliced, streched
|
// C) 9-sliced, streched
|
||||||
// the sprite is 9-sliced and streched.
|
// the sprite is 9-sliced and streched.
|
||||||
if (_numberOfSlices == 1) {
|
if (_numberOfSlices == 1) {
|
||||||
setTextureCoords(_rect, &_quad);
|
|
||||||
Rect copyRect;
|
Rect copyRect;
|
||||||
if (_strechEnabled) {
|
if (_strechEnabled) {
|
||||||
// case B)
|
// case B)
|
||||||
|
@ -451,12 +452,13 @@ void Sprite::updatePoly()
|
||||||
_rect.size.width,
|
_rect.size.width,
|
||||||
_rect.size.height);
|
_rect.size.height);
|
||||||
}
|
}
|
||||||
|
setTextureCoords(_rect, &_quad);
|
||||||
setVertexCoords(copyRect, &_quad);
|
setVertexCoords(copyRect, &_quad);
|
||||||
_polyInfo.setQuad(&_quad);
|
_polyInfo.setQuad(&_quad);
|
||||||
} else {
|
} else {
|
||||||
// case C)
|
// case C)
|
||||||
|
|
||||||
// in theory it can support 3 slices as well, but let's stick to 9 only
|
// in theory it can support 3 or 6 slices as well, but let's stick to 9 only
|
||||||
CCASSERT(_numberOfSlices == 9, "Invalid number of slices");
|
CCASSERT(_numberOfSlices == 9, "Invalid number of slices");
|
||||||
|
|
||||||
|
|
||||||
|
@ -647,11 +649,23 @@ void Sprite::updatePoly()
|
||||||
Rect(x2, y2, x2_s, y2_s), // top-right
|
Rect(x2, y2, x2_s, y2_s), // top-right
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// needed in order to get color from "_quad"
|
||||||
|
V3F_C4B_T2F_Quad tmpQuad = _quad;
|
||||||
|
|
||||||
for (int i=0; i<_numberOfSlices; ++i) {
|
for (int i=0; i<_numberOfSlices; ++i) {
|
||||||
setTextureCoords(texRects[i], &_quads[i]);
|
setTextureCoords(texRects[i], &tmpQuad);
|
||||||
setVertexCoords(verticesRects[i], &_quads[i]);
|
setVertexCoords(verticesRects[i], &tmpQuad);
|
||||||
|
populateTriangle(i, tmpQuad);
|
||||||
}
|
}
|
||||||
_polyInfo.setQuads(_quads, _numberOfSlices);
|
TrianglesCommand::Triangles triangles;
|
||||||
|
triangles.verts = _trianglesVertex;
|
||||||
|
triangles.vertCount = 16;
|
||||||
|
triangles.indices = _trianglesIndex;
|
||||||
|
triangles.indexCount = 6 * 9; // 9 quads, each needs 6 vertices
|
||||||
|
|
||||||
|
// probably we can update the _trianglesCommand directly
|
||||||
|
// to avoid memcpy'ing stuff
|
||||||
|
_polyInfo.setTriangles(triangles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,21 +681,29 @@ void Sprite::setCenterRectNormalized(const cocos2d::Rect &rectTopLeft)
|
||||||
// convert it to 1-slice
|
// convert it to 1-slice
|
||||||
if (rect.equals(Rect(0,0,1,1))) {
|
if (rect.equals(Rect(0,0,1,1))) {
|
||||||
_numberOfSlices = 1;
|
_numberOfSlices = 1;
|
||||||
free(_quads);
|
free(_trianglesVertex);
|
||||||
_quads = nullptr;
|
free(_trianglesIndex);
|
||||||
|
_trianglesVertex = nullptr;
|
||||||
|
_trianglesIndex = nullptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// convert it to 9-slice if it isn't already
|
// convert it to 9-slice if it isn't already
|
||||||
if (_numberOfSlices != 9) {
|
if (_numberOfSlices != 9) {
|
||||||
_numberOfSlices = 9;
|
_numberOfSlices = 9;
|
||||||
_quads = (V3F_C4B_T2F_Quad*) malloc(sizeof(*_quads) * 9);
|
// 9 quads + 7 exterior points = 16
|
||||||
|
_trianglesVertex = (V3F_C4B_T2F*) malloc(sizeof(*_trianglesVertex) * (9 + 3 + 4));
|
||||||
|
// 9 quads, each needs 6 vertices = 54
|
||||||
|
_trianglesIndex = (unsigned short*) malloc(sizeof(*_trianglesIndex) * 6 * 9);
|
||||||
|
|
||||||
|
// populate indices in CCW direction
|
||||||
for (int i=0; i<9; ++i) {
|
for (int i=0; i<9; ++i) {
|
||||||
_quads[i].bl.colors = Color4B::WHITE;
|
_trianglesIndex[i * 6 + 0] = (i * 4 / 3) + 4;
|
||||||
_quads[i].br.colors = Color4B::WHITE;
|
_trianglesIndex[i * 6 + 1] = (i * 4 / 3) + 0;
|
||||||
_quads[i].tl.colors = Color4B::WHITE;
|
_trianglesIndex[i * 6 + 2] = (i * 4 / 3) + 5;
|
||||||
_quads[i].tr.colors = Color4B::WHITE;
|
_trianglesIndex[i * 6 + 3] = (i * 4 / 3) + 1;
|
||||||
|
_trianglesIndex[i * 6 + 4] = (i * 4 / 3) + 5;
|
||||||
|
_trianglesIndex[i * 6 + 5] = (i * 4 / 3) + 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,12 +801,12 @@ void Sprite::setTextureCoords(const Rect& rectInPoints, V3F_C4B_T2F_Quad* outQua
|
||||||
#endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
#endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
|
||||||
|
|
||||||
|
|
||||||
if ((_flippedX && !_rectRotated) || (_flippedY && _rectRotated))
|
if ((!_rectRotated && _flippedX) || (_rectRotated && _flippedY))
|
||||||
{
|
{
|
||||||
std::swap(left, right);
|
std::swap(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_flippedY && !_rectRotated) || (_flippedX && _rectRotated))
|
if ((!_rectRotated && _flippedY) || (_rectRotated && _flippedX))
|
||||||
{
|
{
|
||||||
std::swap(top, bottom);
|
std::swap(top, bottom);
|
||||||
}
|
}
|
||||||
|
@ -862,6 +884,61 @@ void Sprite::setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sprite::populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad)
|
||||||
|
{
|
||||||
|
CCASSERT(quadIndex < 9, "Invalid quadIndex");
|
||||||
|
// convert Quad intro Triangle since it takes less memory
|
||||||
|
|
||||||
|
// Triangles are ordered like the following:
|
||||||
|
// Numbers: Quad Index
|
||||||
|
// Letters: triangles' vertices
|
||||||
|
//
|
||||||
|
// M-----N-----O-----P
|
||||||
|
// | | | |
|
||||||
|
// | 6 | 7 | 8 |
|
||||||
|
// | | | |
|
||||||
|
// I-----J-----K-----L
|
||||||
|
// | | | |
|
||||||
|
// | 3 | 4 | 5 |
|
||||||
|
// | | | |
|
||||||
|
// E-----F-----G-----H
|
||||||
|
// | | | |
|
||||||
|
// | 0 | 1 | 2 |
|
||||||
|
// | | | |
|
||||||
|
// A-----B-----C-----D
|
||||||
|
//
|
||||||
|
// So, if QuadIndex == 4, then it should update vertices J,K,F,G
|
||||||
|
|
||||||
|
// Optimization: I don't need to copy all the vertices all the time. just the 4 "quads" from the corners.
|
||||||
|
if (quadIndex == 0 || quadIndex == 2 || quadIndex == 6 || quadIndex == 8)
|
||||||
|
{
|
||||||
|
if (_flippedX) {
|
||||||
|
if (quadIndex % 3 == 0)
|
||||||
|
quadIndex += 2;
|
||||||
|
else
|
||||||
|
quadIndex -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_flippedY) {
|
||||||
|
if (quadIndex <= 2)
|
||||||
|
quadIndex += 6;
|
||||||
|
else
|
||||||
|
quadIndex -= 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int index_bl = quadIndex * 4 / 3;
|
||||||
|
const int index_br = index_bl + 1;
|
||||||
|
const int index_tl = index_bl + 4;
|
||||||
|
const int index_tr = index_bl + 5;
|
||||||
|
|
||||||
|
|
||||||
|
_trianglesVertex[index_tr] = quad.tr;
|
||||||
|
_trianglesVertex[index_br] = quad.br;
|
||||||
|
_trianglesVertex[index_tl] = quad.tl;
|
||||||
|
_trianglesVertex[index_bl] = quad.bl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: visit, draw, transform
|
// MARK: visit, draw, transform
|
||||||
|
|
||||||
|
|
|
@ -631,6 +631,7 @@ protected:
|
||||||
virtual void setTextureCoords(const Rect& rect);
|
virtual void setTextureCoords(const Rect& rect);
|
||||||
virtual void setTextureCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
|
virtual void setTextureCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
|
||||||
virtual void setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
|
virtual void setVertexCoords(const Rect& rect, V3F_C4B_T2F_Quad* outQuad);
|
||||||
|
void populateTriangle(int quadIndex, const V3F_C4B_T2F_Quad& quad);
|
||||||
virtual void updateBlendFunc();
|
virtual void updateBlendFunc();
|
||||||
virtual void setReorderChildDirtyRecursively();
|
virtual void setReorderChildDirtyRecursively();
|
||||||
virtual void setDirtyRecursively(bool value);
|
virtual void setDirtyRecursively(bool value);
|
||||||
|
@ -680,7 +681,8 @@ protected:
|
||||||
|
|
||||||
// vertex coords, texture coords and color info
|
// vertex coords, texture coords and color info
|
||||||
V3F_C4B_T2F_Quad _quad;
|
V3F_C4B_T2F_Quad _quad;
|
||||||
V3F_C4B_T2F_Quad* _quads;
|
V3F_C4B_T2F* _trianglesVertex;
|
||||||
|
unsigned short* _trianglesIndex;
|
||||||
PolygonInfo _polyInfo;
|
PolygonInfo _polyInfo;
|
||||||
|
|
||||||
// opacity and RGB protocol
|
// opacity and RGB protocol
|
||||||
|
|
Loading…
Reference in New Issue