void DrawFrame() { _forceDraw = false; if (_currentFrame >= frames.Length) { graphics.ClearMesh(); } else { Frame frame = frames[_currentFrame]; if (frame.rect.width == 0) { graphics.ClearMesh(); } else { Rect uvRect = frame.uvRect; if (_flip != FlipType.None) { ToolSet.FlipRect(ref uvRect, _flip); } graphics.DrawRect(frame.rect, uvRect, _color); if (frame.rotated) { NGraphics.RotateUV(graphics.uv, ref uvRect); } graphics.UpdateMesh(); } } }
void LoadFont(PackageItem item) { BitmapFont font = new BitmapFont(item); item.bitmapFont = font; ByteBuffer buffer = item.rawData; buffer.Seek(0, 0); bool ttf = buffer.ReadBool(); font.canTint = buffer.ReadBool(); font.resizable = buffer.ReadBool(); font.hasChannel = buffer.ReadBool(); int fontSize = buffer.ReadInt(); int xadvance = buffer.ReadInt(); int lineHeight = buffer.ReadInt(); float texScaleX = 1; float texScaleY = 1; NTexture mainTexture = null; AtlasSprite mainSprite = null; if (ttf && _sprites.TryGetValue(item.id, out mainSprite)) { mainTexture = (NTexture)GetItemAsset(mainSprite.atlas); texScaleX = mainTexture.root.uvRect.width / mainTexture.width; texScaleY = mainTexture.root.uvRect.height / mainTexture.height; } buffer.Seek(0, 1); BitmapFont.BMGlyph bg; int cnt = buffer.ReadInt(); for (int i = 0; i < cnt; i++) { int nextPos = buffer.ReadShort(); nextPos += buffer.position; bg = new BitmapFont.BMGlyph(); char ch = buffer.ReadChar(); font.AddChar(ch, bg); string img = buffer.ReadS(); int bx = buffer.ReadInt(); int by = buffer.ReadInt(); bg.offsetX = buffer.ReadInt(); bg.offsetY = buffer.ReadInt(); bg.width = buffer.ReadInt(); bg.height = buffer.ReadInt(); bg.advance = buffer.ReadInt(); bg.channel = buffer.ReadByte(); if (bg.channel == 1) { bg.channel = 3; } else if (bg.channel == 2) { bg.channel = 2; } else if (bg.channel == 3) { bg.channel = 1; } if (ttf) { if (mainSprite.rotated) { bg.uv[0] = new Vector2((float)(by + bg.height + mainSprite.rect.x) * texScaleX, 1 - (float)(mainSprite.rect.yMax - bx) * texScaleY); bg.uv[1] = new Vector2(bg.uv[0].x - (float)bg.height * texScaleX, bg.uv[0].y); bg.uv[2] = new Vector2(bg.uv[1].x, bg.uv[0].y + (float)bg.width * texScaleY); bg.uv[3] = new Vector2(bg.uv[0].x, bg.uv[2].y); } else { bg.uv[0] = new Vector2((float)(bx + mainSprite.rect.x) * texScaleX, 1 - (float)(by + bg.height + mainSprite.rect.y) * texScaleY); bg.uv[1] = new Vector2(bg.uv[0].x, bg.uv[0].y + (float)bg.height * texScaleY); bg.uv[2] = new Vector2(bg.uv[0].x + (float)bg.width * texScaleX, bg.uv[1].y); bg.uv[3] = new Vector2(bg.uv[2].x, bg.uv[0].y); } bg.lineHeight = lineHeight; } else { PackageItem charImg; if (_itemsById.TryGetValue(img, out charImg)) { GetItemAsset(charImg); Rect uvRect = charImg.texture.uvRect; bg.uv[0] = uvRect.position; bg.uv[1] = new Vector2(uvRect.xMin, uvRect.yMax); bg.uv[2] = new Vector2(uvRect.xMax, uvRect.yMax); bg.uv[3] = new Vector2(uvRect.xMax, uvRect.yMin); if (charImg.texture.rotated) { NGraphics.RotateUV(bg.uv, ref uvRect); } bg.width = charImg.texture.width; bg.height = charImg.texture.height; if (mainTexture == null) { mainTexture = charImg.texture.root; } } if (fontSize == 0) { fontSize = bg.height; } if (bg.advance == 0) { if (xadvance == 0) { bg.advance = bg.offsetX + bg.width; } else { bg.advance = xadvance; } } bg.lineHeight = bg.offsetY < 0 ? bg.height : (bg.offsetY + bg.height); if (bg.lineHeight < font.size) { bg.lineHeight = font.size; } } buffer.position = nextPos; } font.size = fontSize; font.mainTexture = mainTexture; if (!font.hasChannel) { font.shader = ShaderConfig.imageShader; } }
/// <summary> /// 截取当前图片的一部分输出到另一个Mesh。不支持图片的填充模式、九宫格的平铺模式。 /// </summary> /// <param name="mesh">目标Mesh</param> /// <param name="localRect">制定图片的区域</param> public void PrintTo(Mesh mesh, Rect localRect) { if (_requireUpdateMesh) { Rebuild(); } Rect uvRect = _texture.uvRect; if (_flip != FlipType.None) { ToolSet.FlipRect(ref uvRect, _flip); } Vector3[] verts; Vector2[] uv; Color32[] colors; int[] triangles; int vertCount = 0; if (!_scaleByTile || _scale9Grid == null || (_texture.width == _contentRect.width && _texture.height == _contentRect.height)) { verts = new Vector3[graphics.vertices.Length]; uv = new Vector2[graphics.uv.Length]; Rect bound = ToolSet.Intersection(ref _contentRect, ref localRect); float u0 = bound.xMin / _contentRect.width; float u1 = bound.xMax / _contentRect.width; float v0 = (_contentRect.height - bound.yMax) / _contentRect.height; float v1 = (_contentRect.height - bound.yMin) / _contentRect.height; u0 = Mathf.Lerp(uvRect.xMin, uvRect.xMax, u0); u1 = Mathf.Lerp(uvRect.xMin, uvRect.xMax, u1); v0 = Mathf.Lerp(uvRect.yMin, uvRect.yMax, v0); v1 = Mathf.Lerp(uvRect.yMin, uvRect.yMax, v1); NGraphics.FillUVOfQuad(uv, 0, Rect.MinMaxRect(u0, v0, u1, v1)); bound.x = 0; bound.y = 0; NGraphics.FillVertsOfQuad(verts, 0, bound); vertCount += 4; } else if (_scaleByTile) { verts = new Vector3[graphics.vertices.Length]; uv = new Vector2[graphics.uv.Length]; int hc = Mathf.CeilToInt(_contentRect.width / _texture.width); int vc = Mathf.CeilToInt(_contentRect.height / _texture.height); float tailWidth = _contentRect.width - (hc - 1) * _texture.width; float tailHeight = _contentRect.height - (vc - 1) * _texture.height; Vector2 offset = Vector2.zero; for (int i = 0; i < hc; i++) { for (int j = 0; j < vc; j++) { Rect rect = new Rect(i * _texture.width, j * _texture.height, i == (hc - 1) ? tailWidth : _texture.width, j == (vc - 1) ? tailHeight : _texture.height); Rect uvTmp = uvRect; if (i == hc - 1) { uvTmp.xMax = Mathf.Lerp(uvRect.xMin, uvRect.xMax, tailWidth / _texture.width); } if (j == vc - 1) { uvTmp.yMin = Mathf.Lerp(uvRect.yMin, uvRect.yMax, 1 - tailHeight / _texture.height); } Rect bound = ToolSet.Intersection(ref rect, ref localRect); if (bound.xMax - bound.xMin >= 0 && bound.yMax - bound.yMin > 0) { float u0 = (bound.xMin - rect.x) / rect.width; float u1 = (bound.xMax - rect.x) / rect.width; float v0 = (rect.y + rect.height - bound.yMax) / rect.height; float v1 = (rect.y + rect.height - bound.yMin) / rect.height; u0 = Mathf.Lerp(uvTmp.xMin, uvTmp.xMax, u0); u1 = Mathf.Lerp(uvTmp.xMin, uvTmp.xMax, u1); v0 = Mathf.Lerp(uvTmp.yMin, uvTmp.yMax, v0); v1 = Mathf.Lerp(uvTmp.yMin, uvTmp.yMax, v1); NGraphics.FillUVOfQuad(uv, vertCount, Rect.MinMaxRect(u0, v0, u1, v1)); if (i == 0 && j == 0) { offset = new Vector2(bound.x, bound.y); } bound.x -= offset.x; bound.y -= offset.y; NGraphics.FillVertsOfQuad(verts, vertCount, bound); vertCount += 4; } } } } else { Rect gridRect = (Rect)_scale9Grid; if (_flip != FlipType.None) { ToolSet.FlipInnerRect(_texture.width, _texture.height, ref gridRect, _flip); } GenerateGrids(gridRect, uvRect); verts = new Vector3[36]; uv = new Vector2[36]; Vector2 offset = new Vector2(); Rect drawRect; Rect texRect; int row, col; float u0, u1, v0, v1; for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; drawRect = Rect.MinMaxRect(gridX[col], gridY[row], gridX[col + 1], gridY[row + 1]); texRect = Rect.MinMaxRect(gridTexX[col], gridTexY[row + 1], gridTexX[col + 1], gridTexY[row]); Rect bound = ToolSet.Intersection(ref drawRect, ref localRect); if (bound.xMax - bound.xMin >= 0 && bound.yMax - bound.yMin > 0) { u0 = (bound.xMin - drawRect.x) / drawRect.width; u1 = (bound.xMax - drawRect.x) / drawRect.width; v0 = (drawRect.yMax - bound.yMax) / drawRect.height; v1 = (drawRect.yMax - bound.yMin) / drawRect.height; u0 = Mathf.Lerp(texRect.xMin, texRect.xMax, u0); u1 = Mathf.Lerp(texRect.xMin, texRect.xMax, u1); v0 = Mathf.Lerp(texRect.yMin, texRect.yMax, v0); v1 = Mathf.Lerp(texRect.yMin, texRect.yMax, v1); NGraphics.FillUVOfQuad(uv, vertCount, Rect.MinMaxRect(u0, v0, u1, v1)); if (vertCount == 0) { offset = new Vector2(bound.x, bound.y); } bound.x -= offset.x; bound.y -= offset.y; NGraphics.FillVertsOfQuad(verts, vertCount, bound); vertCount += 4; } } } if (vertCount != verts.Length) { Array.Resize(ref verts, vertCount); Array.Resize(ref uv, vertCount); } int triangleCount = (vertCount >> 1) * 3; triangles = new int[triangleCount]; int k = 0; for (int i = 0; i < vertCount; i += 4) { triangles[k++] = i; triangles[k++] = i + 1; triangles[k++] = i + 2; triangles[k++] = i + 2; triangles[k++] = i + 3; triangles[k++] = i; } colors = new Color32[vertCount]; for (int i = 0; i < vertCount; i++) { Color col = _color; col.a = this.alpha; colors[i] = col; } if (_texture.rotated) { NGraphics.RotateUV(uv, ref uvRect); } mesh.Clear(); mesh.vertices = verts; mesh.uv = uv; mesh.triangles = triangles; mesh.colors32 = colors; }
virtual protected void Rebuild() { _requireUpdateMesh = false; if (_texture == null) { graphics.ClearMesh(); return; } Rect uvRect = _texture.uvRect; if (_flip != FlipType.None) { ToolSet.FlipRect(ref uvRect, _flip); } if (_fillMethod != FillMethod.None) { graphics.DrawRectWithFillMethod(_contentRect, uvRect, _color, _fillMethod, _fillAmount, _fillOrigin, _fillClockwise); } else if (_texture.width == _contentRect.width && _texture.height == _contentRect.height) { graphics.DrawRect(_contentRect, uvRect, _color); } else if (_scaleByTile) { //如果纹理是repeat模式,而且单独占满一张纹理,那么可以用repeat的模式优化显示 if (_texture.nativeTexture != null && _texture.nativeTexture.wrapMode == TextureWrapMode.Repeat && uvRect.x == 0 && uvRect.y == 0 && uvRect.width == 1 && uvRect.height == 1) { uvRect.width *= _contentRect.width / _texture.width; uvRect.height *= _contentRect.height / _texture.height; graphics.DrawRect(_contentRect, uvRect, _color); } else { TileFill(_contentRect, uvRect, _texture.width, _texture.height, -1); graphics.FillColors(_color); graphics.FillTriangles(); } } else if (_scale9Grid != null) { Rect gridRect = (Rect)_scale9Grid; if (_flip != FlipType.None) { ToolSet.FlipInnerRect(_texture.width, _texture.height, ref gridRect, _flip); } GenerateGrids(gridRect, uvRect); if (_tileGridIndice == 0) { graphics.Alloc(16); int k = 0; for (int cy = 0; cy < 4; cy++) { for (int cx = 0; cx < 4; cx++) { graphics.uv[k] = new Vector2(gridTexX[cx], gridTexY[cy]); graphics.vertices[k] = new Vector2(gridX[cx], -gridY[cy]); k++; } } graphics.FillTriangles(NGraphics.TRIANGLES_9_GRID); } else { int hc, vc; Rect drawRect; Rect texRect; int row, col; int part; //先计算需要的顶点数量 int vertCount = 0; for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; part = gridTileIndice[pi]; if (part != -1 && (_tileGridIndice & (1 << part)) != 0) { if (part == 0 || part == 1 || part == 4) { hc = Mathf.CeilToInt((gridX[col + 1] - gridX[col]) / gridRect.width); } else { hc = 1; } if (part == 2 || part == 3 || part == 4) { vc = Mathf.CeilToInt((gridY[row + 1] - gridY[row]) / gridRect.height); } else { vc = 1; } vertCount += hc * vc * 4; } else { vertCount += 4; } } graphics.Alloc(vertCount); int k = 0; for (int pi = 0; pi < 9; pi++) { col = pi % 3; row = pi / 3; part = gridTileIndice[pi]; drawRect = Rect.MinMaxRect(gridX[col], gridY[row], gridX[col + 1], gridY[row + 1]); texRect = Rect.MinMaxRect(gridTexX[col], gridTexY[row + 1], gridTexX[col + 1], gridTexY[row]); if (part != -1 && (_tileGridIndice & (1 << part)) != 0) { k = TileFill(drawRect, texRect, (part == 0 || part == 1 || part == 4) ? gridRect.width : drawRect.width, (part == 2 || part == 3 || part == 4) ? gridRect.height : drawRect.height, k); } else { graphics.FillVerts(k, drawRect); graphics.FillUV(k, texRect); k += 4; } } graphics.FillTriangles(); } graphics.FillColors(_color); } else { graphics.DrawRect(_contentRect, uvRect, _color); } if (_texture.rotated) { NGraphics.RotateUV(graphics.uv, ref uvRect); } graphics.UpdateMesh(); }