一个三角形3个顶点,一个8个三角形,4个四边形
- 如果瓦片在同一张纹理上不会出现裂缝问题
网络异常,图片无法展示|网络异常,图片无法展示|
- 如果瓦片在不同的纹理上就会会出现裂缝问题
网络异常,图片无法展示|网络异常,图片无法展示|
tiled.tml文件内容,tmx格式
<?xml version="1.0" encoding="UTF-8"?> <map version="1.5" tiledversion="1.6.0" orientation="orthogonal" renderorder="right-down" width="2" height="1" tilewidth="32" tileheight="32" infinite="0" mapScale="1" nextlayerid="2" nextobjectid="1"> <tileset firstgid="1" name="2" tilewidth="32" tileheight="32" tilecount="1" columns="1"> <image source="2.png" width="32" height="32"/> </tileset> <tileset firstgid="2" name="1" tilewidth="32" tileheight="32" tilecount="1" columns="1"> <image source="1.png" width="32" height="32"/> </tileset> <layer id="1" name="图块层 1" width="2" height="1"> <data encoding="csv">2,1</data> </layer> </map> 复制代码
- CCFastTMXTiledMap.cpp
bool TMXTiledMap::initWithTMXFile(const std::string& tmxFile) { TMXMapInfo *mapInfo = TMXMapInfo::create(tmxFile); buildWithMapInfo(mapInfo); return true; } 复制代码
- CCTMXXMLParser.cpp
bool TMXMapInfo::initWithTMXFile(const std::string& tmxFile) { return parseXMLFile(_TMXFileName); // xml解析,使用的SAX解析流 } void TMXMapInfo::startElement(void* /*ctx*/, const char *name, const char **atts) { TMXMapInfo *tmxMapInfo = this; std::string elementName = name; ValueMap attributeDict; if (atts && atts[0]) { // 属性是一个一维数组,所以要+2 for (int i = 0; atts[i]; i += 2) { std::string key = atts[i]; std::string value = atts[i+1]; attributeDict.emplace(key, Value(value)); } } } TMXTilesetInfo tmxMapInfo->getTilesets().pushBack(tileset); TMXLayerInfo tmxMapInfo->getLayers().pushBack(layer); 在endElement的时候会设置每一层的tiles layer->_tiles void TMXLayer::setupTiles(){ int length = _TileSetGroup.size(); for(int i=0; i<length; ++i){ _TileSetGroup[i]._set->_imageSize = _TileSetGroup[i]._texture->getContentSizeInPixels(); // 设置图集纹理参数 _TileSetGroup[i]._texture->setAliasTexParameters(); } } 复制代码
TMX下边会有TMXLayer这个节点
网络异常,图片无法展示
|
void TMXLayer::updateTotalQuads(const Rect& culledRect) 渲染命令 std::vector<PrimitiveCommand> _renderCommands; 复制代码
在线框模式下,很明显看到提交的顶点是分离的
网络异常,图片无法展示
|
- CCPrimitive.cpp
void Primitive::draw(){ if(_verts){ _verts->use(); } } 复制代码
- CCVertexIndexData.cpp
void VertexData::use() { uint32_t flags(0); for(auto& element : _vertexStreams) { flags = flags | (1 << element.second._stream._semantic); } GL::enableVertexAttribs(flags); int lastVBO = -1; for(auto& element : _vertexStreams) { //glEnableVertexAttribArray((GLint)element.second._stream._semantic); auto vertexStreamAttrib = element.second._stream; auto vertexBuffer = element.second._buffer; // don't call glBindBuffer() if not needed. Expensive operation. int vbo = vertexBuffer->getVBO(); if (vbo != lastVBO) { // 顶点的数据来源,vertexBuffer的vbo glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer->getVBO()); lastVBO = vbo; } glVertexAttribPointer(GLint(vertexStreamAttrib._semantic), vertexStreamAttrib._size, vertexStreamAttrib._type, vertexStreamAttrib._normalize, vertexBuffer->getSizePerVertex(), (GLvoid*)((long)vertexStreamAttrib._offset)); } } 复制代码
- 更新顶点的逻辑
void TMXLayer::updateVertexBuffer() { GL::bindVAO(0); if(nullptr == _vData) { _vertexBuffer = VertexBuffer::create(sizeof(V3F_C4B_T2F), (int)_totalQuads.size() * 4); _vData = VertexData::create(); _vData->setStream(_vertexBuffer, VertexStreamAttribute(0, GLProgram::VERTEX_ATTRIB_POSITION, GL_FLOAT, 3)); _vData->setStream(_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, colors), GLProgram::VERTEX_ATTRIB_COLOR, GL_UNSIGNED_BYTE, 4, true)); _vData->setStream(_vertexBuffer, VertexStreamAttribute(offsetof(V3F_C4B_T2F, texCoords), GLProgram::VERTEX_ATTRIB_TEX_COORD, GL_FLOAT, 2)); CC_SAFE_RETAIN(_vData); CC_SAFE_RETAIN(_vertexBuffer); } if(_vertexBuffer) { // 顶点信息来源:_totalQuads,顶点坐标没有问题 _vertexBuffer->updateVertices((void*)&_totalQuads[0], (int)_totalQuads.size() * 4, 0); } } 复制代码
使用的shader: SHADER_NAME_POSITION_TEXTURE_COLOR
varying vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_Position = CC_MVPMatrix * a_position; v_fragmentColor = a_color; v_texCoord = a_texCoord; } 复制代码
varying vec4 v_fragmentColor; varying vec2 v_texCoord; void main() { gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); } 复制代码
CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
struct CC_DLL V3F_C4B_T2F { /// vertices (3F) Vec3 vertices; // 12 bytes /// colors (4B) Color4B colors; // 4 bytes // tex coords (2F) Tex2F texCoords; // 8 bytes }; 复制代码
测试使用sprite拼接,是没有缝隙的
最终焦点聚集到了纹理参数上
网络异常,图片无法展示
|
GL_TEXTURE_MIN_FILTER
缩小
- GL_NEAREST: OpenGL会选择中心点最接近纹理坐标的那个像素
- GL_LINEAR
- GL_NEAREST_MIPMAP_NEAREST
- GL_LINEAR_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
:默认值- GL_LINEAR_MIPMAP_LINEAR
GL_TEXTURE_MAG_FILTER
放大
- GL_NEAREST
GL_LINEAR
:默认值
发现调整为LINER也没有解决缝隙的问题
cocos creator 2.4.8没有这个问题
const auto& matrixP = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
Mat4 matrixMVP = matrixP * matrixMV;
确认是MPV矩阵的问题
gl_Position = CC_MVPMatrix * a_position;
当我尝试将顶点的范围控制在[-1, 1]
时,将CC_MVPMatrix矩阵移除计算过程,发现线框模式下,就没有再出现缝隙了
网络异常,图片无法展示
|
至此,可以确定就是MVP矩阵出现了问题。
观察有bug和没有bug的矩阵value
平移会影响12,13
网络异常,图片无法展示
|
网络异常,图片无法展示
|
再次追击问题
发现MVP矩阵都是相同的,再次验证矩阵是没有问题的
网络异常,图片无法展示
|
gl_Position = CC_MVPMatrix * a_position;
很可能z的不同,在经过矩阵计算后,导致x、y也发生了变化,之前的焦点一直聚集在x、y上,导致忽略了这个问题。
那么z是如何产生的呢?