public void DrawMaterialClipped(string name, int frame, float x, float y, Alignment alignment, ColorRgba color, float clipX, float clipY) { GraphicResource res; if (graphics.TryGetValue(name, out res)) { Texture texture = res.Material.Res.MainTexture.Res; if (frame < 0) { frame = (int)(Time.GameTimer.TotalSeconds * 0.86f * res.FrameCount / res.FrameDuration) % res.FrameCount; } Rect uv = texture.LookupAtlas(frame); float w = texture.InternalWidth * uv.W; float h = texture.InternalHeight * uv.H; uv.W *= clipX; uv.H *= clipY; Vector2 originPos = new Vector2(x, y); alignment.ApplyTo(ref originPos, new Vector2(w, h)); canvas.State.SetMaterial(res.Material); canvas.State.ColorTint = color; canvas.State.TextureCoordinateRect = uv; canvas.FillRect((int)originPos.X, (int)originPos.Y, w * clipX, h * clipY); } }
public static void Draw(this GraphicResource res, Canvas c, int frame, float x, float y, Alignment alignment, ColorRgba color, float scaleX = 1f, float scaleY = 1f) { Texture texture = res.Material.Res.MainTexture.Res; if (texture == null) { return; } if (frame < 0) { // ToDo: HUD Animations are slowed down to 0.86f, adjust this in Metadata files frame = (int)(Time.GameTimer.TotalSeconds * 0.86f * res.FrameCount / res.FrameDuration) % res.FrameCount; } Rect uv = texture.LookupAtlas(frame); float w = texture.InternalWidth * scaleX * uv.W; float h = texture.InternalHeight * scaleY * uv.H; Vector2 originPos = new Vector2(x, y); alignment.ApplyTo(ref originPos, new Vector2(w, h)); c.State.SetMaterial(res.Material); c.State.ColorTint = color; c.State.TextureCoordinateRect = uv; c.FillRect((int)originPos.X, (int)originPos.Y, w, h); }
private void DrawMaterial(Canvas c, string id, float x, float y, Alignment alignment, float scale = 1f) { GraphicResource res; if (!graphics.TryGetValue(id, out res)) { return; } int curAnimFrame = (int)(Time.GameTimer.TotalSeconds * res.FrameCount / res.FrameDuration) % res.FrameCount; Vector2 originPos = new Vector2(x, y); alignment.ApplyTo(ref originPos, new Vector2(res.FrameDimensions.X * scale, res.FrameDimensions.Y * scale)); c.State.SetMaterial(res.Material); /*c.State.TextureCoordinateRect = new Rect( * (float)(curAnimFrame % res.FrameConfiguration.X) / res.FrameConfiguration.X, * (float)(curAnimFrame / res.FrameConfiguration.X) / res.FrameConfiguration.Y, * (1f / res.FrameConfiguration.X), * (1f / res.FrameConfiguration.Y) * );*/ c.State.TextureCoordinateRect = res.Material.Res.MainTexture.Res.LookupAtlas(curAnimFrame); c.FillRect(originPos.X, originPos.Y, res.FrameDimensions.X * scale, res.FrameDimensions.Y * scale); }
// GraphicResources public static void Draw(this GraphicResource res, Canvas c, float x, float y, Alignment alignment, ColorRgba color, float scaleX = 1f, float scaleY = 1f) { Texture texture = res.Material.Res.MainTexture.Res; if (texture == null) { return; } Vector2 originPos = new Vector2(x, y); alignment.ApplyTo(ref originPos, new Vector2(texture.InternalWidth * scaleX, texture.InternalHeight * scaleY)); c.State.SetMaterial(res.Material); c.State.ColorTint = color; c.FillRect((int)originPos.X, (int)originPos.Y, texture.InternalWidth * scaleX, texture.InternalHeight * scaleY); }
public unsafe void DrawString(ref int charOffset, string text, float x, float y, Alignment alignment, ColorRgba?color = null, float scale = 1f, float angleOffset = 0f, float varianceX = 4f, float varianceY = 4f, float speed = 4f, float charSpacing = 1f, float lineSpacing = 1f) { if (string.IsNullOrEmpty(text)) { return; } float phase = (float)Time.GameTimer.TotalSeconds * speed; bool hasColor = false; // Pre-compute text size //int lines = 1; float totalWidth = 0f, lastWidth = 0f, totalHeight = 0f; float charSpacingPre = charSpacing; float scalePre = scale; for (int i = 0; i < text.Length; i++) { if (text[i] == '\n') { if (lastWidth < totalWidth) { lastWidth = totalWidth; } totalWidth = 0f; totalHeight += (height * scale * lineSpacing); //lines++; continue; } else if (text[i] == '\f' && text[i + 1] == '[') { i += 2; int formatIndex = i; while (text[i] != ']') { i++; } if (text[formatIndex + 1] == ':') { int paramInt; switch (text[formatIndex]) { case 'c': // Color hasColor = true; break; case 's': // Scale //if (int.TryParse(new string(ptr, formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (int.TryParse(text.Substring(formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { scalePre = paramInt * 0.01f; } break; case 'w': // Char spacing //if (int.TryParse(new string(ptr, formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (int.TryParse(text.Substring(formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { charSpacingPre = paramInt * 0.01f; } break; } } continue; } Rect uvRect = chars[(byte)text[i]]; if (uvRect.W > 0 && uvRect.H > 0) { totalWidth += (uvRect.W + spacing) * charSpacingPre * scalePre; } } if (lastWidth < totalWidth) { lastWidth = totalWidth; } totalHeight += (height * scale * lineSpacing); //VertexC1P3T2[] vertexData = new VertexC1P3T2[text.Length * 4]; VertexC1P3T2[] vertexData = canvas.RentVertices(text.Length * 4); // Set default material bool colorize, allowColorChange; ContentRef <Material> material; ColorRgba mainColor; if (color.HasValue) { mainColor = color.Value; if (mainColor == ColorRgba.TransparentBlack) { if (hasColor) { material = materialColor; mainColor = new ColorRgba(0.46f, 0.46f, 0.4f, 0.5f); } else { material = materialPlain; mainColor = ColorRgba.White; } } else { material = materialColor; } colorize = false; if (mainColor.R == 0 && mainColor.G == 0 && mainColor.B == 0) { allowColorChange = false; } else { allowColorChange = true; } } else { material = materialColor; mainColor = ColorRgba.White; colorize = true; allowColorChange = false; } Vector2 uvRatio = new Vector2( 1f / materialPlain.Res.MainTexture.Res.ContentWidth, 1f / materialPlain.Res.MainTexture.Res.ContentHeight ); int vertexBaseIndex = 0; Vector2 originPos = new Vector2(x, y); alignment.ApplyTo(ref originPos, new Vector2(lastWidth /** scale*/, totalHeight /*lines * height * scale * lineSpacing*/)); float lineStart = originPos.X; for (int i = 0; i < text.Length; i++) { if (text[i] == '\n') { // New line originPos.X = lineStart; originPos.Y += (height * scale * lineSpacing); continue; } else if (text[i] == '\f' && text[i + 1] == '[') { // Format i += 2; int formatIndex = i; while (text[i] != ']') { i++; } if (text[formatIndex + 1] == ':') { int paramInt; switch (text[formatIndex]) { case 'c': // Color //if (allowColorChange && int.TryParse(new string(ptr, formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (allowColorChange && int.TryParse(text.Substring(formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (paramInt == -1) { colorize = true; } else { colorize = false; mainColor = colors[paramInt % colors.Length]; } } break; case 's': // Scale //if (int.TryParse(new string(ptr, formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (int.TryParse(text.Substring(formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { scale = paramInt * 0.01f; } break; case 'w': // Char spacing //if (int.TryParse(new string(ptr, formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { if (int.TryParse(text.Substring(formatIndex + 2, i - (formatIndex + 2)), out paramInt)) { charSpacing = paramInt * 0.01f; } break; } } continue; } Rect uvRect = chars[(byte)text[i]]; if (uvRect.W > 0 && uvRect.H > 0) { if (colorize) { mainColor = colors[charOffset % colors.Length]; } Vector3 pos = new Vector3(originPos); if (angleOffset > 0f) { pos.X += MathF.Cos((phase + charOffset) * angleOffset * MathF.Pi) * varianceX * scale; pos.Y += MathF.Sin((phase + charOffset) * angleOffset * MathF.Pi) * varianceY * scale; } pos.X = MathF.Round(pos.X); pos.Y = MathF.Round(pos.Y); float x2 = MathF.Round(pos.X + uvRect.W * scale); float y2 = MathF.Round(pos.Y + uvRect.H * scale); vertexData[vertexBaseIndex + 0].Pos = pos; vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X; vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y; vertexData[vertexBaseIndex + 0].Color = mainColor; vertexData[vertexBaseIndex + 1].Pos.X = pos.X; vertexData[vertexBaseIndex + 1].Pos.Y = y2; vertexData[vertexBaseIndex + 1].Pos.Z = pos.Z; vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X; vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.Y + uvRect.H * uvRatio.Y; vertexData[vertexBaseIndex + 1].Color = mainColor; vertexData[vertexBaseIndex + 2].Pos.X = x2; vertexData[vertexBaseIndex + 2].Pos.Y = y2; vertexData[vertexBaseIndex + 2].Pos.Z = pos.Z; vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.X + uvRect.W * uvRatio.X; vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.Y + uvRect.H * uvRatio.Y; vertexData[vertexBaseIndex + 2].Color = mainColor; vertexData[vertexBaseIndex + 3].Pos.X = x2; vertexData[vertexBaseIndex + 3].Pos.Y = pos.Y; vertexData[vertexBaseIndex + 3].Pos.Z = pos.Z; vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.X + uvRect.W * uvRatio.X; vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y; vertexData[vertexBaseIndex + 3].Color = mainColor; if (MathF.RoundToInt(canvas.DrawDevice.TargetSize.X) != (MathF.RoundToInt(canvas.DrawDevice.TargetSize.X) / 2) * 2) { float align = 0.5f / canvas.DrawDevice.TargetSize.X; vertexData[vertexBaseIndex + 0].Pos.X += align; vertexData[vertexBaseIndex + 1].Pos.X += align; vertexData[vertexBaseIndex + 2].Pos.X += align; vertexData[vertexBaseIndex + 3].Pos.X += align; } if (MathF.RoundToInt(canvas.DrawDevice.TargetSize.Y) != (MathF.RoundToInt(canvas.DrawDevice.TargetSize.Y) / 2) * 2) { float align = 0.5f * scale / canvas.DrawDevice.TargetSize.Y; vertexData[vertexBaseIndex + 0].Pos.Y += align; vertexData[vertexBaseIndex + 1].Pos.Y += align; vertexData[vertexBaseIndex + 2].Pos.Y += align; vertexData[vertexBaseIndex + 3].Pos.Y += align; } vertexBaseIndex += 4; originPos.X += ((uvRect.W + spacing) * scale * charSpacing); } charOffset++; } charOffset++; // Submit all the vertices as one draw batch canvas.DrawDevice.AddVertices( material, VertexMode.Quads, vertexData, 0, vertexBaseIndex); }