public override void Draw(IDrawDevice device) { if (animHidden) { return; } Texture mainTex = RetrieveMainTex(); DrawTechnique tech = RetrieveDrawTechnique(); Rect uvRect, uvRectNext; bool smoothShaderInput = (tech != null && tech.PreferredVertexFormat == VertexC1P3T4A1.Declaration); GetAnimData(mainTex, smoothShaderInput, out uvRect, out uvRectNext); if (!smoothShaderInput) { PrepareVertices(ref vertices, device, this.colorTint, uvRect); if (customMat != null) { device.AddVertices(customMat, VertexMode.Quads, vertices, 0, 4); } else { if (flipMode == 0) { device.AddVertices(sharedMat, VertexMode.Quads, vertices, 0, 4); } else { BatchInfo material = device.RentMaterial(sharedMat.Res.Info); material.SetValue("normalMultiplier", new Vector2((flipMode & FlipMode.Horizontal) == 0 ? 1 : -1f, (flipMode & FlipMode.Vertical) == 0 ? 1 : -1f)); device.AddVertices(material, VertexMode.Quads, vertices, 0, 4); } } } else { PrepareVerticesSmooth(ref verticesSmooth, device, curAnimFrameFade, this.colorTint, uvRect, uvRectNext); if (customMat != null) { device.AddVertices(customMat, VertexMode.Quads, verticesSmooth, 0, 4); } else { if (flipMode == 0) { device.AddVertices(sharedMat, VertexMode.Quads, verticesSmooth, 0, 4); } else { BatchInfo material = device.RentMaterial(sharedMat.Res.Info); material.SetValue("normalMultiplier", new Vector2((flipMode & FlipMode.Horizontal) == 0 ? 1 : -1f, (flipMode & FlipMode.Vertical) == 0 ? 1 : -1f)); device.AddVertices(material, VertexMode.Quads, verticesSmooth, 0, 4); } } } }
private void RenderTexturedBackground(IDrawDevice device) { if (!cachedTexturedBackground.IsAvailable) { return; } float timeMult = Time.TimeMult; backgroundX += timeMult * 1.2f; backgroundY += timeMult * -0.2f + timeMult * MathF.Sin(backgroundPhase) * 0.6f; backgroundPhase += timeMult * 0.001f; Vector3 renderPos = new Vector3(0, 0, 600); // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets renderPos.X = MathF.Round(renderPos.X); renderPos.Y = MathF.Round(renderPos.Y); if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2) { renderPos.X += 0.5f; } if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2) { // AMD Bugfix? renderPos.Y -= 0.004f; } // Reserve the required space for vertex data in our locally cached buffer int neededVertices = 4; if (cachedVertices == null || cachedVertices.Length < neededVertices) { cachedVertices = new VertexC1P3T2[neededVertices]; } // Render it as world-space fullscreen quad cachedVertices[0].Pos = new Vector3(renderPos.X, renderPos.Y, renderPos.Z); cachedVertices[1].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y, renderPos.Z); cachedVertices[2].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y + device.TargetSize.Y, renderPos.Z); cachedVertices[3].Pos = new Vector3(renderPos.X, renderPos.Y + device.TargetSize.Y, renderPos.Z); cachedVertices[0].TexCoord = new Vector2(0.0f, 0.0f); cachedVertices[1].TexCoord = new Vector2(1f, 0.0f); cachedVertices[2].TexCoord = new Vector2(1f, 1f); cachedVertices[3].TexCoord = new Vector2(0.0f, 1f); cachedVertices[0].Color = cachedVertices[1].Color = cachedVertices[2].Color = cachedVertices[3].Color = ColorRgba.White; // Setup custom pixel shader BatchInfo material = device.RentMaterial(); material.Technique = texturedBackgroundShader; material.MainTexture = cachedTexturedBackground; material.SetValue("horizonColor", horizonColor); material.SetValue("shift", new Vector2(backgroundX, backgroundY)); material.SetValue("parallaxStarsEnabled", 0f); device.AddVertices(material, VertexMode.Quads, cachedVertices, 0, 4); }
/// <summary> /// Rents a temporary material instance for rendering, based on the specified <see cref="BatchInfo"/>. /// The instance is returned implicitly when the device is done with the current rendering operation. /// </summary> /// <param name="device"></param> /// <param name="baseMaterial"></param> public static BatchInfo RentMaterial(this IDrawDevice device, BatchInfo baseMaterial) { BatchInfo material = device.RentMaterial(); material.InitFrom(baseMaterial); return(material); }
/// <summary> /// Rents a temporary material instance for rendering, based on the specified <see cref="Material"/>. /// The instance is returned implicitly when the device is done with the current rendering operation. /// </summary> /// <param name="device"></param> /// <param name="baseMaterial"></param> public static BatchInfo RentMaterial(this IDrawDevice device, ContentRef <Material> baseMaterial) { return(device.RentMaterial( baseMaterial.IsAvailable ? baseMaterial.Res.Info : Material.Checkerboard.Res.Info)); }
public void RenderTexturedBackground(IDrawDevice device, ref TileMapLayer layer, int cacheIndex, float x, float y) { if (!cachedTexturedBackground.IsAvailable || cachedTexturedBackgroundAnimated) { RecreateTexturedBackground(ref layer); } // Fit the input material rect to the output size according to rendering step config Vector3 renderPos = new Vector3(device.ViewerPos.X - device.TargetSize.X / 2, device.ViewerPos.Y - device.TargetSize.Y / 2, layer.Depth); // Fit the target rect to actual pixel coordinates to avoid unnecessary filtering offsets renderPos.X = MathF.Round(renderPos.X); renderPos.Y = MathF.Round(renderPos.Y); if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2) { renderPos.X += 0.5f; } if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2) { // AMD Bugfix? renderPos.Y -= 0.004f; } // Reserve the required space for vertex data in our locally cached buffer int neededVertices = 4; if (cachedVertices == null || cachedVertices.Length < neededVertices) { cachedVertices = new VertexC1P3T2[neededVertices]; } // Render it as world-space fullscreen quad cachedVertices[0].Pos = new Vector3(renderPos.X, renderPos.Y, renderPos.Z); cachedVertices[1].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y, renderPos.Z); cachedVertices[2].Pos = new Vector3(renderPos.X + device.TargetSize.X, renderPos.Y + device.TargetSize.Y, renderPos.Z); cachedVertices[3].Pos = new Vector3(renderPos.X, renderPos.Y + device.TargetSize.Y, renderPos.Z); cachedVertices[0].TexCoord = new Vector2(0f, 0f); cachedVertices[1].TexCoord = new Vector2(1f, 0f); cachedVertices[2].TexCoord = new Vector2(1f, 1f); cachedVertices[3].TexCoord = new Vector2(0f, 1f); cachedVertices[0].Color = cachedVertices[1].Color = cachedVertices[2].Color = cachedVertices[3].Color = ColorRgba.White; // Setup custom pixel shader BatchInfo material = device.RentMaterial(); material.Technique = texturedBackgroundShader; material.MainTexture = cachedTexturedBackground; material.SetValue("horizonColor", layer.BackgroundColor); material.SetValue("shift", new Vector2(x, y)); material.SetValue("parallaxStarsEnabled", layer.ParallaxStarsEnabled ? 1f : 0f); device.AddVertices(material, VertexMode.Quads, cachedVertices, 0, 4); }
private void OnRender(IDrawDevice device) { if (framesLeft <= 0) { OnCinematicsEnd(true); return; } frameProgress += Time.TimeMult; if (frameProgress >= frameDelay) { frameProgress -= frameDelay; framesLeft--; PrepareNextFrame(); } // Render current frame canvas.Begin(device); BatchInfo material = device.RentMaterial(); material.MainTexture = videoTexture; canvas.State.SetMaterial(material); Vector2 targetSize = device.TargetSize; float ratioTarget = targetSize.Y / targetSize.X; float ratioSource = (float)height / width; float ratio = MathF.Clamp(ratioTarget, ratioSource - 0.16f, ratioSource); float fillHeight = targetSize.X * ratio; float yOffset = (targetSize.Y - fillHeight) * 0.5f; canvas.FillRect(0, yOffset, targetSize.X, fillHeight); canvas.End(); }
public void Draw(IDrawDevice device) { if (mode == Mode.None) { return; } float progressTime = time; if (mode == Mode.FadeOut) { progressTime = 1f - progressTime; } material.Res.SetValue("progressTime", progressTime); ((DrawDevice)device).AddFullscreenQuad(device.RentMaterial(material), TargetResize.Fill); time += timeIncrement * Time.TimeMult; if (time >= 1f) { isCompleted = true; } }
public override void OnPaint(Canvas canvas, Rect view) { IDrawDevice device = canvas.DrawDevice; Vector2 center = device.TargetSize * 0.5f; const float topLine = 96f; float bottomLine = device.TargetSize.Y - 42; api.DrawMaterial("MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f)); int charOffset = 0; if (levelList.Count > 0) { const float itemSpacing = 17f; float topItem = topLine - 4f; float bottomItem = bottomLine - 10f; float contentHeight = bottomItem - topItem; float maxVisibleItemsFloat = (contentHeight / itemSpacing); maxVisibleItems = (int)maxVisibleItemsFloat; float currentItem = topItem + itemSpacing + (maxVisibleItemsFloat - maxVisibleItems) * 0.5f * itemSpacing; // ToDo: ... float column2 = device.TargetSize.X * 0.55f; float sx = column2 * 1.52f; float column1 = column2 * 0.36f + view.X; column2 *= 1.1f; for (int i = 0; i < maxVisibleItems; i++) { int idx = i + scrollOffset; if (idx >= levelList.Count) { break; } if (selectedIndex == idx) { charOffset = 0; float xMultiplier = levelList[idx].DisplayName.Length * 0.5f; float easing = Ease.OutElastic(animation); float x = column1 + xMultiplier - easing * xMultiplier; float size = 0.7f + easing * 0.12f; // Column 2 api.DrawStringShadow(ref charOffset, levelList[idx].LevelName, column2, currentItem, Alignment.Left, new ColorRgba(0.48f, 0.5f), 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); // Column 1 api.DrawStringShadow(ref charOffset, levelList[idx].DisplayName, x, currentItem, Alignment.Left, null, size, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); // Column 0 api.DrawStringShadow(ref charOffset, levelList[idx].Icon, column1 - 16f, currentItem, Alignment.Right, new ColorRgba(0.48f, 0.5f), size, 0.4f, 1f, 1f, 8f, charSpacing: 0.68f); } else { // Column 2 api.DrawString(ref charOffset, levelList[idx].LevelName, column2, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); // Column 1 api.DrawString(ref charOffset, levelList[idx].DisplayName, column1, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); // Column 0 api.DrawString(ref charOffset, levelList[idx].Icon, column1 - 16f, currentItem, Alignment.Right, ColorRgba.TransparentBlack, 0.7f, charSpacing: 0.7f); } currentItem += itemSpacing; } // Scrollbar if (levelList.Count > maxVisibleItems) { const float sw = 3f; float sy = ((float)scrollOffset / levelList.Count) * 18f * maxVisibleItems + topLine; float sh = ((float)maxVisibleItems / levelList.Count) * 16f * maxVisibleItems; BatchInfo mat1 = device.RentMaterial(); mat1.Technique = DrawTechnique.Alpha; mat1.MainColor = new ColorRgba(0f, 0f, 0f, 0.28f); canvas.State.SetMaterial(mat1); canvas.FillRect(sx + 1f, sy + 1f, sw, sh); BatchInfo mat2 = device.RentMaterial(); mat2.Technique = DrawTechnique.Alpha; mat2.MainColor = new ColorRgba(0.8f, 0.8f, 0.8f, 0.5f); canvas.State.SetMaterial(mat2); canvas.FillRect(sx, sy, sw, sh); } // Loading if (isLoadingAnimation > 0f) { if (!isLoading) { isLoadingAnimation -= Time.TimeMult * 0.03f; } else { isLoadingAnimation = 1f; } float loadingX = center.X - 50f; float loadingY = center.Y; float startAngle = (float)(Time.GameTimer.TotalSeconds * 6.0f); float time = (float)(Time.GameTimer.TotalSeconds * 1.3f) % 2f; bool reverse = (time >= 1f); if (reverse) { time -= 1f; } float timeCubed = MathF.Pow(time, 3); float timeQuad = MathF.Pow(time, 4); float timeQuint = MathF.Pow(time, 5); float endAngle; if (reverse) { endAngle = startAngle + MathF.TwoPi * (1 - ((6 * timeQuint) + (-15 * timeQuad) + (10 * timeCubed))); } else { endAngle = startAngle + MathF.TwoPi * ((6 * timeQuint) + (-15 * timeQuad) + (10 * timeCubed)); } const float r1 = 7f; const float r2 = r1 - 0.4f; const float r3 = r2 - 0.4f; const float r4 = r3 - 0.4f; api.DrawMaterial("MenuDim", loadingX + 50f, loadingY, Alignment.Center, new ColorRgba(1f, 0.7f * isLoadingAnimation), 40f, 10f); BatchInfo mat1 = device.RentMaterial(); mat1.Technique = DrawTechnique.Alpha; mat1.MainColor = new ColorRgba(0f, 0.2f * isLoadingAnimation); canvas.State.SetMaterial(mat1); canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r1, startAngle, endAngle); canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r2, startAngle, endAngle); canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r3, startAngle, endAngle); canvas.DrawCircleSegment(loadingX + 1.6f, loadingY + 1.6f, r4, startAngle, endAngle); BatchInfo mat2 = device.RentMaterial(); mat2.Technique = DrawTechnique.Alpha; mat2.MainColor = new ColorRgba(0.95f, 0.8f * isLoadingAnimation); canvas.State.SetMaterial(mat2); canvas.DrawCircleSegment(loadingX, loadingY, r1, startAngle, endAngle); canvas.DrawCircleSegment(loadingX, loadingY, r2, startAngle, endAngle); canvas.DrawCircleSegment(loadingX, loadingY, r3, startAngle, endAngle); canvas.DrawCircleSegment(loadingX, loadingY, r4, startAngle, endAngle); api.DrawStringShadow(ref charOffset, "loading".T(), loadingX + r1 + 10f, loadingY + 2f, Alignment.Left, new ColorRgba(0.48f, 0.5f * isLoadingAnimation), 0.8f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f); } } else { api.DrawStringShadow(ref charOffset, "menu/play custom/single/empty".T(), center.X, center.Y, Alignment.Center, new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f); } api.DrawMaterial("MenuLine", 0, center.X, topLine, Alignment.Center, ColorRgba.White, 1.6f); api.DrawMaterial("MenuLine", 1, center.X, bottomLine, Alignment.Center, ColorRgba.White, 1.6f); }
public override void OnPaint(Canvas canvas, Rect view) { IDrawDevice device = canvas.DrawDevice; Vector2 center = device.TargetSize * 0.5f; const float topLine = 96f; float bottomLine = device.TargetSize.Y - 42; api.DrawMaterial("MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f)); int charOffset = 0; int itemCount = 0; if (serverList.Count > 0) { const float itemSpacing = 17f; float topItem = topLine - 4f; float bottomItem = bottomLine - 10f; float contentHeight = bottomItem - topItem; float maxVisibleItemsFloat = (contentHeight / itemSpacing); maxVisibleItems = (int)maxVisibleItemsFloat; float currentItem = topItem + itemSpacing + (maxVisibleItemsFloat - maxVisibleItems) * 0.5f * itemSpacing; float column2 = device.TargetSize.X * 0.55f; float sx = column2 * 1.52f; float column1 = column2; float column3 = column2; column1 *= 0.3f; column2 *= 0.78f; column3 *= 1.08f; for (int i = 0; i < maxVisibleItems; i++) { int idx = i + scrollOffset; if (idx >= serverList.Count) { break; } ServerDiscovery.Server server = serverList[idx]; if (server.IsLost && server.LatencyMs < 0) { continue; } string infoText = server.CurrentPlayers + " / " + server.MaxPlayers + " "; ColorRgba infoColor; if (server.LatencyMs < 0) { infoText += "- ms"; infoColor = new ColorRgba(0.48f, 0.5f); } else if (server.LatencyMs > 10000) { infoText = "menu/play custom/multi/unreachable".T(); infoColor = new ColorRgba(0.45f, 0.27f, 0.22f, 0.5f); } else { infoText += server.LatencyMs + " ms"; float playersRatio = (float)(server.CurrentPlayers / server.MaxPlayers); if (server.LatencyMs < 50 && playersRatio < 0.9f) { infoColor = new ColorRgba(0.2f, 0.45f, 0.2f, 0.5f); } else if (server.LatencyMs < 100 && playersRatio < 0.9f) { infoColor = new ColorRgba(0.45f, 0.45f, 0.21f, 0.5f); } else if (server.LatencyMs < 200 && playersRatio < 0.95f) { infoColor = new ColorRgba(0.5f, 0.4f, 0.2f, 0.5f); } else if (server.LatencyMs < 400 && playersRatio < 0.99f) { infoColor = new ColorRgba(0.47f, 0.35f, 0.3f, 0.5f); } else { infoColor = new ColorRgba(0.45f, 0.27f, 0.22f, 0.5f); } } string name = server.Name; if (name.Length > 32) { name = name.Substring(0, 31) + "..."; } string endpoint = server.ActiveEndPointName; if (endpoint.Length > 26) { endpoint = endpoint.Substring(0, 25) + "..."; } if (selectedIndex == idx) { charOffset = 0; float xMultiplier = name.Length * 0.5f; float easing = Ease.OutElastic(animation); float x = column1 + xMultiplier - easing * xMultiplier; float size = 0.7f + easing * 0.1f; // Column 2 api.DrawStringShadow(ref charOffset, infoText, column2, currentItem, Alignment.Left, infoColor, 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); // Column 3 api.DrawStringShadow(ref charOffset, endpoint, column3, currentItem, Alignment.Left, new ColorRgba(0.48f, 0.5f), 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); // Column 1 api.DrawStringShadow(ref charOffset, name, x, currentItem, Alignment.Left, null, size, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); } else { // Column 2 api.DrawString(ref charOffset, infoText, column2, currentItem, Alignment.Left, infoColor, 0.7f); // Column 3 api.DrawString(ref charOffset, endpoint, column3, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); // Column 1 api.DrawString(ref charOffset, name, column1, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); } currentItem += itemSpacing; itemCount++; } // Scrollbar if (itemCount > maxVisibleItems) { const float sw = 3f; float sy = ((float)scrollOffset / itemCount) * 18f * maxVisibleItems + topLine; float sh = ((float)maxVisibleItems / itemCount) * 16f * maxVisibleItems; BatchInfo mat1 = device.RentMaterial(); mat1.Technique = DrawTechnique.Alpha; mat1.MainColor = new ColorRgba(0f, 0f, 0f, 0.28f); canvas.State.SetMaterial(mat1); canvas.FillRect(sx + 1f, sy + 1f, sw, sh); BatchInfo mat2 = device.RentMaterial(); mat2.Technique = DrawTechnique.Alpha; mat2.MainColor = new ColorRgba(0.8f, 0.8f, 0.8f, 0.5f); canvas.State.SetMaterial(mat2); canvas.FillRect(sx, sy, sw, sh); } } if (itemCount == 0) { api.DrawStringShadow(ref charOffset, "menu/play custom/multi/empty".T(), center.X, center.Y, Alignment.Center, new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f); } api.DrawMaterial("MenuLine", 0, center.X, topLine, Alignment.Center, ColorRgba.White, 1.6f); api.DrawMaterial("MenuLine", 1, center.X, bottomLine, Alignment.Center, ColorRgba.White, 1.6f); }
public override void OnPaint(Canvas canvas) { IDrawDevice device = canvas.DrawDevice; Vector2 center = device.TargetSize * 0.5f; const float topLine = 96f; float bottomLine = device.TargetSize.Y - 42; api.DrawMaterial(c, "MenuDim", center.X, (topLine + bottomLine) * 0.5f, Alignment.Center, ColorRgba.White, 55f, (bottomLine - topLine) * 0.063f, new Rect(0f, 0.3f, 1f, 0.4f)); int charOffset = 0; if (serverList.Count > 0) { float topItem = topLine; float bottomItem = bottomLine; float contentHeight = bottomItem - topItem; const float itemSpacing = 17f; itemCount = (int)(contentHeight / itemSpacing); float currentItem = topItem + itemSpacing; // ToDo: ... float column2 = device.TargetSize.X * 0.55f; float sx = column2 * 1.52f; float column1 = column2; float column3 = column2; column1 *= 0.3f; column2 *= 0.78f; column3 *= 1.08f; for (int i_ = 0; i_ < itemCount; i_++) { int i = xOffset + i_; if (i >= serverList.Count) { break; } Server server = serverList[i]; if (selectedIndex == i) { charOffset = 0; float xMultiplier = server.Name.Length * 0.5f; float easing = Ease.OutElastic(animation); float x = column1 + xMultiplier - easing * xMultiplier; float size = 0.7f + easing * 0.1f; // Column 2 api.DrawStringShadow(device, ref charOffset, server.CurrentPlayers + " / " + server.MaxPlayers + " " + server.LatencyMs + " ms", column2, currentItem, Alignment.Left, new ColorRgba(0.48f, 0.5f), 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.8f); // Column 3 api.DrawStringShadow(device, ref charOffset, server.EndPoint.ToString(), column3, currentItem, Alignment.Left, new ColorRgba(0.48f, 0.5f), 0.8f, 0.4f, 1f, 1f, 8f, charSpacing: 0.8f); // Column 1 api.DrawStringShadow(device, ref charOffset, server.Name, x, currentItem, Alignment.Left, null, size, 0.4f, 1f, 1f, 8f, charSpacing: 0.88f); } else { // Column 2 api.DrawString(device, ref charOffset, server.CurrentPlayers + " / " + server.MaxPlayers + " " + server.LatencyMs + " ms", column2, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); // Column 3 api.DrawString(device, ref charOffset, server.EndPoint.ToString(), column3, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); // Column 1 api.DrawString(device, ref charOffset, server.Name, column1, currentItem, Alignment.Left, ColorRgba.TransparentBlack, 0.7f); } currentItem += itemSpacing; } // Scrollbar if (serverList.Count > itemCount) { const float sw = 3f; float sy = ((float)xOffset / serverList.Count) * 18f * itemCount + topLine; float sh = ((float)itemCount / serverList.Count) * 16f * itemCount; BatchInfo mat1 = device.RentMaterial(); mat1.Technique = DrawTechnique.Alpha; mat1.MainColor = new ColorRgba(0f, 0f, 0f, 0.28f); canvas.State.SetMaterial(mat1); canvas.FillRect(sx + 1f, sy + 1f, sw, sh); BatchInfo mat2 = device.RentMaterial(); mat2.Technique = DrawTechnique.Alpha; mat2.MainColor = new ColorRgba(0.8f, 0.8f, 0.8f, 0.5f); canvas.State.SetMaterial(mat2); canvas.FillRect(sx, sy, sw, sh); } } else { api.DrawStringShadow(device, ref charOffset, "Servers not found!", center.X, center.Y, Alignment.Center, new ColorRgba(0.62f, 0.44f, 0.34f, 0.5f), 0.9f, 0.4f, 0.6f, 0.6f, 8f, charSpacing: 0.88f); } api.DrawMaterial(c, "MenuLine", 0, center.X, topLine, Alignment.Center, ColorRgba.White, 1.6f); api.DrawMaterial(c, "MenuLine", 1, center.X, bottomLine, Alignment.Center, ColorRgba.White, 1.6f); }
protected internal override void OnCollectDrawcalls(Canvas canvas) { base.OnCollectDrawcalls(canvas); IDrawDevice device = canvas.DrawDevice; GridLayerData displayedData = default(GridLayerData); this.View.ActiveState.GetDisplayedGridData(Point.Empty, ref displayedData); float distanceToCamera = 0.0f - device.ViewerPos.Z; if (distanceToCamera <= device.NearZ) { return; } float alphaTemp = 0.5f; alphaTemp *= (float)Math.Min(1.0d, ((distanceToCamera - device.NearZ) / (device.NearZ * 5.0f))); if (alphaTemp <= 0.005f) { return; } ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp); float gridVisualMinSize = 50.0f; Vector2 gridBaseSize = displayedData.GridBaseSize; if (gridBaseSize.X <= 0.0f) { gridBaseSize.X = 100.0f; } if (gridBaseSize.Y <= 0.0f) { gridBaseSize.Y = 100.0f; } Vector2 adjustedGridBaseSize; adjustedGridBaseSize.X = gridBaseSize.X * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.X)); adjustedGridBaseSize.Y = gridBaseSize.Y * MathF.NextPowerOfTwo((int)MathF.Ceiling(gridVisualMinSize / gridBaseSize.Y)); float scaleAtGrid = device.GetScaleAtZ(0.0f); float scaleAdjustmentFactor = 4.0f * MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleAtGrid, 2.0f))); Vector2 adjustedGridSize; adjustedGridSize.X = MathF.Max(adjustedGridBaseSize.X * scaleAdjustmentFactor, gridBaseSize.X); adjustedGridSize.Y = MathF.Max(adjustedGridBaseSize.Y * scaleAdjustmentFactor, gridBaseSize.Y); Vector2 stepSize = adjustedGridSize; float viewBoundRad = MathF.Distance(device.TargetSize.X, device.TargetSize.Y) * 0.5f / scaleAtGrid; int lineCountX = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / stepSize.X)) * 4; int lineCountY = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / stepSize.Y)) * 4; int vertexCount = (lineCountX * 2 + lineCountY * 2); if (this.vertexBuffer == null) { this.vertexBuffer = new RawList <VertexC1P3>(vertexCount); } this.vertexBuffer.Count = vertexCount; VertexC1P3[] vertices = this.vertexBuffer.Data; float beginPos; float pos; int lineIndex; int vertOff = 0; beginPos = stepSize.X * (int)(device.ViewerPos.X / stepSize.X - (lineCountX / 8)); pos = beginPos; lineIndex = 0; for (int x = 0; x < lineCountX; x++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + x * 2 + 0].Pos.X = pos; vertices[vertOff + x * 2 + 0].Pos.Y = device.ViewerPos.Y - viewBoundRad; vertices[vertOff + x * 2 + 0].Pos.Z = 0.0f; vertices[vertOff + x * 2 + 0].DepthOffset = 1.0f; vertices[vertOff + x * 2 + 1] = vertices[vertOff + x * 2 + 0]; vertices[vertOff + x * 2 + 1].Pos.Y = device.ViewerPos.Y + viewBoundRad; pos += stepSize.X / 4; lineIndex++; } vertOff += lineCountX * 2; beginPos = stepSize.Y * (int)(device.ViewerPos.Y / stepSize.Y - (lineCountY / 8)); pos = beginPos; lineIndex = 0; for (int y = 0; y < lineCountY; y++) { bool primaryLine = lineIndex % 4 == 0; bool secondaryLine = lineIndex % 4 == 2; vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f)); vertices[vertOff + y * 2 + 0].Pos.X = device.ViewerPos.X - viewBoundRad; vertices[vertOff + y * 2 + 0].Pos.Y = pos; vertices[vertOff + y * 2 + 0].Pos.Z = 0.0f; vertices[vertOff + y * 2 + 0].DepthOffset = 1.0f; vertices[vertOff + y * 2 + 1] = vertices[vertOff + y * 2 + 0]; vertices[vertOff + y * 2 + 1].Pos.X = device.ViewerPos.X + viewBoundRad; pos += stepSize.Y / 4; lineIndex++; } vertOff += lineCountY * 2; BatchInfo material = device.RentMaterial(); material.Technique = DrawTechnique.Alpha; device.AddVertices(material, VertexMode.Lines, vertices, this.vertexBuffer.Count); }
public override void Draw(IDrawDevice device) { Vector3 posTemp = this.gameobj.Transform.Pos; Vector2 xDot, yDot; MathF.GetTransformDotVec(this.GameObj.Transform.Angle, this.gameobj.Transform.Scale, out xDot, out yDot); // Apply block alignment Vector2 textOffset = Vector2.Zero; Vector2 textSize = this.text.Size; if (this.text.MaxWidth > 0) { textSize.X = this.text.MaxWidth; } this.blockAlign.ApplyTo(ref textOffset, textSize); MathF.TransformDotVec(ref textOffset, ref xDot, ref yDot); posTemp.X += textOffset.X; posTemp.Y += textOffset.Y; if (this.text.Fonts != null && this.text.Fonts.Any(r => r.IsAvailable && r.Res.IsPixelGridAligned)) { posTemp.X = MathF.Round(posTemp.X); posTemp.Y = MathF.Round(posTemp.Y); if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2) { posTemp.X += 0.5f; } if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2) { posTemp.Y += 0.5f; } } int[] vertLen = this.text.EmitVertices( ref this.vertFont, ref this.vertIcon, posTemp.X, posTemp.Y, posTemp.Z, this.colorTint, xDot, yDot); // Apply depth offset to generated vertices for (int i = 0; i < this.vertFont.Length; i++) { for (int j = 0; j < vertLen[i + 1]; j++) { this.vertFont[i][j].DepthOffset = this.offset; } } for (int i = 0; i < vertLen[0]; i++) { this.vertIcon[i].DepthOffset = this.offset; } if (this.text.Fonts != null) { for (int i = 0; i < this.text.Fonts.Length; i++) { if (this.text.Fonts[i] != null && this.text.Fonts[i].IsAvailable) { if (this.customMat == null) { device.AddVertices(this.text.Fonts[i].Res.Material, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]); } else { BatchInfo cm = device.RentMaterial(this.customMat); cm.MainTexture = this.text.Fonts[i].Res.Material.MainTexture; device.AddVertices(cm, VertexMode.Quads, this.vertFont[i], vertLen[i + 1]); } } } } if (this.text.Icons != null && this.iconMat.IsAvailable) { device.AddVertices(this.iconMat, VertexMode.Quads, this.vertIcon, vertLen[0]); } }