| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- //-----------------------------------------------------------------------------
- // LineManager2D.cs
- //
- // Microsoft XNA Community Game Platform
- // Copyright (C) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using RacingGame.Graphics;
- using RacingGame.Helpers;
- using System;
- using System.Collections.Generic;
- using System.Text;
- using RacingGame.Shaders;
- namespace RacingGame.Graphics
- {
- /// <summary>
- /// LineManager class, used for drawing lines. We can't simply draw
- /// lines like in OpenGL (glLine) because we need to do everything with
- /// vertex buffers, which is a bit more work (and using DrawPrimitives
- /// directly produces way worse code).
- /// </summary>
- public class LineManager2D : IDisposable
- {
- /// <summary>
- /// Number of lines used this frame, will be set to 0 when rendering.
- /// </summary>
- private int numOfLines = 0;
- /// <summary>
- /// The actual list for all the lines, it will NOT be reseted each
- /// frame like numOfLines! We will remember the last lines and
- /// only change this list when anything changes (new line, old
- /// line missing, changing line data).
- /// When this happens buildVertexBuffer will be set to true.
- /// </summary>
- private List<Line> lines = new List<Line>();
- /// <summary>
- /// Struct for a line, instances of this struct will be added to lines.
- /// </summary>
- struct Line
- {
- /// <summary>
- /// Positions
- /// </summary>
- public Point startPoint, endPoint;
- /// <summary>
- /// Color
- /// </summary>
- public Color color;
- /// <summary>
- /// Create line
- /// </summary>
- /// <param name="setStartPoint">Set start point</param>
- /// <param name="setEndPoint">Set end point</param>
- /// <param name="setColor">Set color</param>
- public Line(Point setStartPoint,
- Point setEndPoint, Color setColor)
- {
- startPoint = setStartPoint;
- endPoint = setEndPoint;
- color = setColor;
- }
- /// <summary>
- /// Are these two Lines equal?
- /// </summary>
- public static bool operator ==(Line a, Line b)
- {
- return a.startPoint == b.startPoint &&
- a.endPoint == b.endPoint &&
- a.color == b.color;
- }
- /// <summary>
- /// Are these two Lines not equal?
- /// </summary>
- public static bool operator !=(Line a, Line b)
- {
- return a.startPoint != b.startPoint ||
- a.endPoint != b.endPoint ||
- a.color != b.color;
- }
- /// <summary>
- /// Support Equals(.) to keep the compiler happy
- /// (because we used == and !=)
- /// </summary>
- public override bool Equals(object a)
- {
- if (a is Line)
- return (Line)a == this;
- return false;
- }
- /// <summary>
- /// Support GetHashCode() to keep the compiler happy
- /// (because we used == and !=)
- /// </summary>
- public override int GetHashCode()
- {
- return 0; // Not supported or nessescary
- }
- }
- /// <summary>
- /// Build vertex buffer this frame because the line list was changed?
- /// Note: The vertex buffer implementation was removed some time ago,
- /// but this variable is still used to check for updates to lineVertices!
- /// </summary>
- private bool buildVertexBuffer = false;
- /// <summary>
- /// Vertex buffer for all lines
- /// </summary>
- VertexPositionColor[] lineVertices =
- new VertexPositionColor[MaxNumOfLines * 2];
- /// <summary>
- /// Real number of primitives currently used.
- /// </summary>
- private int numOfPrimitives = 0;
- /// <summary>
- /// Max. number of lines allowed.
- /// </summary>
- private const int MaxNumOfLines = 64;
- /// <summary>
- /// Create LineManager
- /// </summary>
- public LineManager2D()
- {
- }
- /// <summary>
- /// Dispose
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- /// <summary>
- /// Dispose
- /// </summary>
- /// <param name="disposing">Disposing</param>
- protected virtual void Dispose(bool disposing)
- {
- }
- /// <summary>
- /// Update vertex buffer
- /// </summary>
- private void UpdateVertexBuffer()
- {
- // Don't do anything if we got no lines.
- if (numOfLines == 0 ||
- // Or if some data is invalid
- lines.Count < numOfLines)
- {
- numOfPrimitives = 0;
- return;
- }
- #if LOG_STUFF
- Log.Write("LineManager.UpdateVertexBuffer() numOfLines=" +
- numOfLines + ", buildVertexBuffer=" + buildVertexBuffer);
- #endif
- // Set all lines
- for (int lineNum = 0; lineNum < numOfLines; lineNum++)
- {
- Line line = (Line)lines[lineNum];
- lineVertices[lineNum * 2 + 0] = new VertexPositionColor(
- new Vector3(
- -1.0f + 2.0f * line.startPoint.X / BaseGame.Width,
- -(-1.0f + 2.0f * line.startPoint.Y / BaseGame.Height), 0),
- line.color);
- lineVertices[lineNum * 2 + 1] = new VertexPositionColor(
- new Vector3(
- -1.0f + 2.0f * line.endPoint.X / BaseGame.Width,
- -(-1.0f + 2.0f * line.endPoint.Y / BaseGame.Height), 0),
- line.color);
- }
- numOfPrimitives = numOfLines;
- // Vertex buffer was build
- buildVertexBuffer = false;
- }
- /// <summary>
- /// Add line
- /// </summary>
- public void AddLine(Point startPoint, Point endPoint, Color color)
- {
- // Don't add new lines if limit is reached
- if (numOfLines >= MaxNumOfLines)
- {
- Log.Write("Too many lines requested in LineManager2D. " +
- "Max lines = " + MaxNumOfLines);
- return;
- }
- // Build line
- Line line = new Line(startPoint, endPoint, color);
- // Check if this exact line exists at the current lines position.
- if (lines.Count > numOfLines)
- {
- if ((Line)lines[numOfLines] != line)
- {
- // overwrite old line, otherwise just increase numOfLines
- lines[numOfLines] = line;
- // Remember to build vertex buffer in Render()
- buildVertexBuffer = true;
- }
- }
- else
- {
- // Then just add new line
- lines.Add(line);
- // Remember to build vertex buffer in Render()
- buildVertexBuffer = true;
- }
- // nextUpValue line
- numOfLines++;
- }
- /// <summary>
- /// Add line with shadow
- /// </summary>
- /// <param name="startPoint">Start point</param>
- /// <param name="endPoint">End point</param>
- /// <param name="color">Color</param>
- public void AddLineWithShadow(Point startPoint, Point endPoint,
- Color color)
- {
- AddLine(new Point(startPoint.X, startPoint.Y + 1),
- new Point(endPoint.X, endPoint.Y + 1), Color.Black);
- AddLine(startPoint, endPoint, color);
- }
- /// <summary>
- /// Render all lines added this frame
- /// </summary>
- public virtual void Render()
- {
- // Need to build vertex buffer?
- if (buildVertexBuffer ||
- numOfPrimitives != numOfLines)
- {
- UpdateVertexBuffer();
- }
- // Render lines if we got any lines to render
- if (numOfPrimitives > 0)
- {
- BaseGame.SetAlphaBlendingEnabled(true);
- BaseGame.WorldMatrix = Matrix.Identity;
- ShaderEffect.lineRendering.Render(
- "LineRendering2D",
- delegate
- {
- BaseGame.Device.DrawUserPrimitives<VertexPositionColor>(
- PrimitiveType.LineList, lineVertices, 0, numOfPrimitives);
- });
- }
- // Ok, finally reset numOfLines for next frame
- numOfLines = 0;
- }
- }
- }
|