cocos2d-x里的TiledMap出现黑线和抖动的解决方案(不影响其他类使用)
2014-02-28 08:42
597 查看
文章转载地址:http://blog.sina.com.cn/s/blog_4508e4860101dzkj.html
今天搞tiled map发现黑边,开始认为是反锯齿问题,但发现无论开启与否都有边,只是程度不同而已。简单网上搜了下发现有解决方案是 修改ccconfig.h让
#define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
1
同时开启tile图块texture的反锯齿避免抖动。
但简单看了下CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL,
发现对texture coordinates作了圈限制。
这是原始的注释:
If enabled, the texture coordinates will be calculated by using this formula:
- texCoord.left = (rect.origin.x*2+1) / (texture.wide*2);
- texCoord.right = texCoord.left + (rect.size.width*2-2)/(texture.wide*2);
The same for bottom and top.
This formula prevents artifacts by using 99% of the texture.
The "correct" way to prevent artifacts is by using the spritesheet-artifact-fixer.py or a similar tool.
Affected nodes:
- CCSprite / CCSpriteBatchNode and subclasses: CCLabelBMFont, CCTMXTiledMap
- CCLabelAtlas
- CCQuadParticleSystem
- CCTileMap
可见影响了全部CCSprite,事实也发现Sprite只要使用的贴图是紧贴边的,周围都有可能都被切掉了一部分。
其实你只要解决tilemap的显示问题,就没必要去动到别的类。简单看了下加载tiledmap相关源码,其实只需很小改动。
首先不要改CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL,
让它仍然是0.
知道的是tiledmap显示部分要用到CCSprite,但这个CCSprite要CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL开启时的作用,
所以这里要新建个CCSprite的子类CCSpriteTileMap。
CCTileMapAtlas.cpp里
CCTileMapAtlas::updateAtlasValueAt 函数中将CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL强行开启
然后找到CCTMXLayer类里面申请new CCSprite的地方替换成new CCSpriteTileMap就OK了。
发现有两处,在这两个函数内
CCTMXLayer::reusedTileWithRect
CCTMXLayer::tileAt
完工!重新BUILD,就看不见恶心的黑线了,同时也不影响别的类使用。
想想如果cocos2d出CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL这个定义最初目的是为了解决tiledmap显示问题的话,为什么不独立出一个针对tiledmap显示问题的编译项呢?当然还有其他目的就另当别论了。
注明下笔者用的cocos2d-x版本是2.1.5,其实2.0.0后版本应该都适用
今天搞tiled map发现黑边,开始认为是反锯齿问题,但发现无论开启与否都有边,只是程度不同而已。简单网上搜了下发现有解决方案是 修改ccconfig.h让
#define CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
1
同时开启tile图块texture的反锯齿避免抖动。
但简单看了下CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL,
发现对texture coordinates作了圈限制。
这是原始的注释:
If enabled, the texture coordinates will be calculated by using this formula:
- texCoord.left = (rect.origin.x*2+1) / (texture.wide*2);
- texCoord.right = texCoord.left + (rect.size.width*2-2)/(texture.wide*2);
The same for bottom and top.
This formula prevents artifacts by using 99% of the texture.
The "correct" way to prevent artifacts is by using the spritesheet-artifact-fixer.py or a similar tool.
Affected nodes:
- CCSprite / CCSpriteBatchNode and subclasses: CCLabelBMFont, CCTMXTiledMap
- CCLabelAtlas
- CCQuadParticleSystem
- CCTileMap
可见影响了全部CCSprite,事实也发现Sprite只要使用的贴图是紧贴边的,周围都有可能都被切掉了一部分。
其实你只要解决tilemap的显示问题,就没必要去动到别的类。简单看了下加载tiledmap相关源码,其实只需很小改动。
首先不要改CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL,
让它仍然是0.
知道的是tiledmap显示部分要用到CCSprite,但这个CCSprite要CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL开启时的作用,
所以这里要新建个CCSprite的子类CCSpriteTileMap。
class CCSpriteTileMap : public CCSprite { protected: virtual void setTextureCoords(CCRect rect); }; void CCSpriteTileMap::setTextureCoords( CCRect rect ) { rect = CC_RECT_POINTS_TO_PIXELS(rect); CCTexture2D *tex = m_pobBatchNode ? m_pobTextureAtlas->getTexture() : m_pobTexture; if (! tex) { return; } float atlasWidth = (float)tex->getPixelsWide(); float atlasHeight = (float)tex->getPixelsHigh(); float left, right, top, bottom; if (m_bRectRotated) { #if 1//CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL left = (2*rect.origin.x+1)/(2*atlasWidth); right = left+(rect.size.height*2-2)/(2*atlasWidth); top = (2*rect.origin.y+1)/(2*atlasHeight); bottom = top+(rect.size.width*2-2)/(2*atlasHeight); #else left = rect.origin.x/atlasWidth; right = (rect.origin.x+rect.size.height) / atlasWidth; top = rect.origin.y/atlasHeight; bottom = (rect.origin.y+rect.size.width) / atlasHeight; #endif // CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL if (m_bFlipX) { CC_SWAP(top, bottom, float); } if (m_bFlipY) { CC_SWAP(left, right, float); } m_sQuad.bl.texCoords.u = left; m_sQuad.bl.texCoords.v = top; m_sQuad.br.texCoords.u = left; m_sQuad.br.texCoords.v = bottom; m_sQuad.tl.texCoords.u = right; m_sQuad.tl.texCoords.v = top; m_sQuad.tr.texCoords.u = right; m_sQuad.tr.texCoords.v = bottom; } else { #if 1//CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL left = (2*rect.origin.x+1)/(2*atlasWidth); right = left + (rect.size.width*2-2)/(2*atlasWidth); top = (2*rect.origin.y+1)/(2*atlasHeight); bottom = top + (rect.size.height*2-2)/(2*atlasHeight); #else left = rect.origin.x/atlasWidth; right = (rect.origin.x + rect.size.width) / atlasWidth; top = rect.origin.y/atlasHeight; bottom = (rect.origin.y + rect.size.height) / atlasHeight; #endif // ! CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL if(m_bFlipX) { CC_SWAP(left,right,float); } if(m_bFlipY) { CC_SWAP(top,bottom,float); } m_sQuad.bl.texCoords.u = left; m_sQuad.bl.texCoords.v = bottom; m_sQuad.br.texCoords.u = right; m_sQuad.br.texCoords.v = bottom; m_sQuad.tl.texCoords.u = left; m_sQuad.tl.texCoords.v = top; m_sQuad.tr.texCoords.u = right; m_sQuad.tr.texCoords.v = top; } }
CCTileMapAtlas.cpp里
CCTileMapAtlas::updateAtlasValueAt 函数中将CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL强行开启
#if 1//CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL float left = (2 * row * itemWidthInPixels + 1) / (2 * textureWide); float right = left + (itemWidthInPixels * 2 - 2) / (2 * textureWide); float top = (2 * col * itemHeightInPixels + 1) / (2 * textureHigh); float bottom = top + (itemHeightInPixels * 2 - 2) / (2 * textureHigh); #else float left = (row * itemWidthInPixels) / textureWide; float right = left + itemWidthInPixels / textureWide; float top = (col * itemHeightInPixels) / textureHigh; float bottom = top + itemHeightInPixels / textureHigh; #endif
然后找到CCTMXLayer类里面申请new CCSprite的地方替换成new CCSpriteTileMap就OK了。
发现有两处,在这两个函数内
CCTMXLayer::reusedTileWithRect
CCTMXLayer::tileAt
完工!重新BUILD,就看不见恶心的黑线了,同时也不影响别的类使用。
想想如果cocos2d出CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL这个定义最初目的是为了解决tiledmap显示问题的话,为什么不独立出一个针对tiledmap显示问题的编译项呢?当然还有其他目的就另当别论了。
注明下笔者用的cocos2d-x版本是2.1.5,其实2.0.0后版本应该都适用
相关文章推荐
- cocos2d-x使用tiledMap时地图格子之间出现黑线、黑色斑点
- cocos2d-x 瓦片地图的黑线及地图抖动解决方案
- cocos2d-x 瓦片地图的黑线及地图抖动解决方案
- 使用wechat4j框架时,在ubuntu tomcat下出现中文乱码问题的解决方案(其他tomcat中文乱码问题可同理参考)
- 关于cocos2d中fast tilemap出现黑线的解决方案
- cocos2d js 使用 cocos studio 合图出现的黑线
- java或者其他语言使用百度地图获取坐标出现app禁用情况的解决方案
- 使用cocos2d-x显示瓦片地图,发现两个瓦片衔接的地方有黑线,找了一下解决方案:
- cocos2d-x tile map瓦片地图的黑线及地图抖动解决方案
- 关于cocos2d中tilemap移动时出现黑线的解决方案
- cocos2d-x 瓦片地图的黑线及地图抖动解决方案
- cocos2d-x tile map瓦片地图的黑线及地图抖动解决方案
- 解决Cocos2d-js 在使用 TiledMap时的黑线问题
- 【转载】cocos2d-x tile map瓦片地图的黑线及地图抖动解决方案
- cocos2d js 使用 cocos studio 合图出现的黑线
- Cocos2d-x使用python创建项目出现WindowsError3错误的解决方案
- cocos2d-x tile map瓦片地图的黑线及地图抖动解决方案
- cocos2d Tiledmap使用心得
- 使用SevenZipSharp出现“Can not load 7-zip library or internal COM error! Message: DLL file does not exist.”的解决方案
- 使用独立模式安装Sharepoint Server 2013出现创建示例数据错误的解决方案