32 using System.Collections.Generic;
33 using Microsoft.Xna.Framework;
34 using Microsoft.Xna.Framework.Graphics;
37 using XnaV2 = Microsoft.Xna.Framework.Vector2;
38 using XnaV3 = Microsoft.Xna.Framework.Vector3;
39 using XnaColor = Microsoft.Xna.Framework.Color;
56 static readonly VertexPositionTexture[] textureVertices =
new VertexPositionTexture[]
58 new VertexPositionTexture(
new XnaV3(-0.5f, 0.5f, 0),
new XnaV2(0.0f, 0.0f) ),
59 new VertexPositionTexture(
new XnaV3(-0.5f, -0.5f, 0),
new XnaV2(0.0f, 1.0f) ),
60 new VertexPositionTexture(
new XnaV3(0.5f, 0.5f, 0),
new XnaV2(1.0f, 0.0f) ),
61 new VertexPositionTexture(
new XnaV3(0.5f, -0.5f, 0),
new XnaV2(1.0f, 1.0f) )
67 static readonly Int16[] textureTriangleIndices =
new short[]
75 static readonly BlendState NoDrawingToScreenBufferBlendState =
new BlendState
77 ColorWriteChannels = ColorWriteChannels.None,
80 static readonly DepthStencilState drawShapeToStencilBufferState =
new DepthStencilState
84 StencilFunction = CompareFunction.Equal,
85 StencilPass = StencilOperation.IncrementSaturation,
88 static readonly DepthStencilState drawAccordingToStencilBufferState =
new DepthStencilState
92 StencilFunction = CompareFunction.LessEqual,
93 StencilPass = StencilOperation.Keep,
96 private static bool isDrawingInsideShape =
false;
97 private static DepthStencilState currentStencilState = DepthStencilState.None;
99 private static VertexPositionTexture[] MakeTextureVertices(
Vector wrapSize )
101 VertexPositionTexture[] tempVertices =
new VertexPositionTexture[textureVertices.Length];
102 for (
int i = 0; i < textureVertices.Length; i++ )
104 tempVertices[i].Position = textureVertices[i].Position;
107 float px = MathHelper.Clamp( (
float)wrapSize.
X, -1, 1 );
108 float py = MathHelper.Clamp( (
float)wrapSize.
Y, -1, 1 );
113 float left = -(float)Math.Sign( wrapSize.
X ) / 2 + 0.5f;
114 float right = left + px;
115 float top = -(float)Math.Sign( wrapSize.
Y ) / 2 + 0.5f;
116 float bottom = top + py;
118 tempVertices[0].TextureCoordinate =
new XnaV2( left, top );
119 tempVertices[1].TextureCoordinate =
new XnaV2( left, bottom );
120 tempVertices[2].TextureCoordinate =
new XnaV2( right, top );
121 tempVertices[3].TextureCoordinate =
new XnaV2( right, bottom );
128 if ( wrapSize.
X == 0 || wrapSize.
Y == 0 )
return;
131 var tempVertices = MakeTextureVertices( wrapSize );
133 device.RasterizerState = RasterizerState.CullClockwise;
136 device.RasterizerState = RasterizerState.CullNone;
139 device.BlendState = BlendState.AlphaBlend;
141 float wrapX = (float)Math.Abs( wrapSize.
X );
142 float wrapY = (float)Math.Abs( wrapSize.
Y );
144 if ( wrapX <= 1 && wrapY <= 1 )
147 DrawImageTexture( texture, matrix, device, tempVertices );
151 float wx = (float)( Math.Sign( wrapSize.
X ) );
152 float wy = (float)( Math.Sign( wrapSize.
Y ) );
153 float tileW = 1 / wrapX;
154 float tileH = 1 / wrapY;
155 float topLeftX = -0.5f + 0.5f * tileW;
156 float topLeftY = 0.5f - 0.5f * tileH;
157 float partX = wrapX - (int)wrapX;
158 float partY = wrapY - (int)wrapY;
160 for (
int y = 0; y < (int)wrapY; y++ )
162 for (
int x = 0; x < (int)wrapX; x++ )
165 Matrix.CreateScale( 1 / wrapX, 1 / wrapY, 1 ) *
166 Matrix.CreateTranslation( topLeftX + x * tileW, topLeftY - y * tileH, 0 ) *
168 DrawImageTexture( texture, m, device, tempVertices );
175 Matrix.CreateScale( partX, 1, 1 ) *
176 Matrix.CreateScale( 1 / wrapX, 1 / wrapY, 1 ) *
177 Matrix.CreateTranslation( -tileW / 2 + tileW * partX / 2, 0, 0 ) *
178 Matrix.CreateTranslation( topLeftX + (
int)wrapX * tileW, topLeftY - y * tileH, 0 ) *
187 for (
int x = 0; x < (int)wrapX; x++ )
191 Matrix.CreateScale( 1, partY, 1 ) *
192 Matrix.CreateScale( 1 / wrapX, 1 / wrapY, 1 ) *
193 Matrix.CreateTranslation( 0, tileH / 2 - tileH * partY / 2, 0 ) *
194 Matrix.CreateTranslation( topLeftX + x * tileW, topLeftY - (
int)wrapY * tileH, 0 ) *
204 Matrix.CreateScale( partX, partY, 1 ) *
205 Matrix.CreateScale( 1 / wrapX, 1 / wrapY, 1 ) *
206 Matrix.CreateTranslation( -tileW / 2 + tileW * partX / 2, tileH / 2 - tileH * partY / 2, 0 ) *
207 Matrix.CreateTranslation( topLeftX + (
int)wrapX * tileW, topLeftY - (
int)wrapY * tileH, 0 ) *
215 private static void DrawImageTexture(
Image texture, Matrix matrix, GraphicsDevice device, VertexPositionTexture[] tempVertices )
217 Effect effect = Graphics.GetTextureEffect( ref matrix, texture.XNATexture,
LightingEnabled );
218 foreach ( EffectPass pass
in effect.CurrentTechnique.Passes )
221 device.SamplerStates[0] = Graphics.GetDefaultSamplerState();
223 PrimitiveType.TriangleList,
224 tempVertices, 0, tempVertices.Length,
225 textureTriangleIndices, 0, textureTriangleIndices.Length / 3
242 throw new ArgumentException(
"The shape must have triangles" );
243 if ( isDrawingInsideShape )
244 throw new Exception(
"EndDrawingInsideShape must be called before calling this function again" );
246 isDrawingInsideShape =
true;
249 device.Clear( ClearOptions.Stencil,
Color.
Black.AsXnaColor(), 0, 0 );
250 device.DepthStencilState = currentStencilState = drawShapeToStencilBufferState;
252 DrawFilledShape( shape.Cache, ref transformation,
Color.
White, NoDrawingToScreenBufferBlendState );
254 device.DepthStencilState = currentStencilState = drawAccordingToStencilBufferState;
259 if ( !isDrawingInsideShape )
260 throw new Exception(
"BeginDrawingInsideShape must be called first" );
263 isDrawingInsideShape =
false;
274 internal static void DrawText(
string text, ref Matrix transformation,
Font font,
Color color )
276 SpriteBatch spriteBatch = Graphics.SpriteBatch;
277 spriteBatch.Begin( SpriteSortMode.FrontToBack, BlendState.AlphaBlend, SamplerState.LinearClamp, currentStencilState, RasterizerState.CullCounterClockwise, null, transformation );
278 spriteBatch.DrawString( font.XnaFont, text, Vector2.Zero, color.AsXnaColor() );
288 DrawImage( texture, ref textureTransformation, textureWrapSize );
298 else if ( shape.Cache.
Triangles != null )
300 DrawFilledShape( shape.Cache, ref matrix, color );
314 VertexPositionColor[] colorVertices =
new VertexPositionColor[2];
315 colorVertices[0].Position =
new Vector3( (
float)segment.
Origin.
X, (
float)segment.
Origin.
Y, 0 );
316 colorVertices[0].Color = color.AsXnaColor();
317 colorVertices[1].Position =
new Vector3( (
float)endPoint.
X, (
float)endPoint.
Y, 0 );
318 colorVertices[1].Color = color.AsXnaColor();
320 BasicEffect effect = Graphics.BasicColorEffect;
321 effect.World = matrix;
322 foreach ( EffectPass pass
in effect.CurrentTechnique.Passes )
325 device.SamplerStates[0] = SamplerState.LinearClamp;
326 device.DrawUserPrimitives<VertexPositionColor>( PrimitiveType.LineStrip, colorVertices, 0, 1 );
333 internal static void DrawRectangle( ref Matrix matrix,
Color color )
345 internal static void DrawFilledShape(
ShapeCache cache, ref Matrix matrix,
Color color )
347 DrawFilledShape( cache, ref matrix, color, BlendState.NonPremultiplied );
350 internal static void DrawFilledShape(
ShapeCache cache, ref Matrix matrix,
Color color, BlendState blendState )
354 VertexPositionColor[] vertices =
new VertexPositionColor[cache.
Vertices.Length];
355 for (
int i = 0; i < vertices.Length; i++ )
358 vertices[i] =
new VertexPositionColor(
new XnaV3( (
float)v.
X, (
float)v.
Y, 0 ), color.AsXnaColor() );
361 Int16[] indices =
new Int16[cache.
Triangles.Length * 3];
362 for (
int i = 0; i < cache.
Triangles.Length; i++ )
369 device.RasterizerState = RasterizerState.CullCounterClockwise;
370 device.BlendState = blendState;
373 device.RasterizerState = RasterizerState.CullNone;
376 Effect effect = Graphics.GetColorEffect( ref matrix,
LightingEnabled );
377 foreach ( EffectPass pass
in effect.CurrentTechnique.Passes )
380 device.SamplerStates[0] = SamplerState.LinearClamp;
381 device.DrawUserIndexedPrimitives<VertexPositionColor>(
382 PrimitiveType.TriangleList,
383 vertices, 0, vertices.Length,
384 indices, 0, indices.Length / 3
391 if ( vertices.Length < 3 )
392 throw new ArgumentException(
"Polygon must have at least three vertices" );
396 VertexPositionColor[] colorVertices =
new VertexPositionColor[vertices.Length];
397 for (
int i = 0; i < colorVertices.Length; i++ )
400 colorVertices[i] =
new VertexPositionColor(
401 new XnaV3( (
float)p.
X, (
float)p.
Y, 0 ),
406 int n = colorVertices.Length;
407 Int16[] indices =
new Int16[2 * n];
408 for (
int i = 0; i < ( n - 1 ); i++ )
410 indices[2 * i] = (Int16)i;
411 indices[2 * i + 1] = (Int16)( i + 1 );
413 indices[2 * ( n - 1 )] = (Int16)( n - 1 );
414 indices[2 * ( n - 1 ) + 1] = (Int16)0;
416 Effect effect = Graphics.GetColorEffect( ref matrix,
LightingEnabled );
417 foreach ( EffectPass pass
in effect.CurrentTechnique.Passes )
420 device.SamplerStates[0] = SamplerState.LinearClamp;
421 device.DrawUserIndexedPrimitives<VertexPositionColor>(
422 PrimitiveType.LineStrip,
423 colorVertices, 0, colorVertices.Length,
424 indices, 0, indices.Length - 1
431 internal static void DrawVertices(
Vector[] vertices, Matrix matrix,
Color color )
433 VertexPositionColor[] pointVertices =
new VertexPositionColor[vertices.Length];
434 for (
int i = 0; i < pointVertices.Length; i++ )
437 pointVertices[i] =
new VertexPositionColor(
438 new XnaV3( (
float)p.
X, (
float)p.
Y, 0 ),
446 BasicEffect effect = Graphics.BasicColorEffect;
447 effect.World = matrix;
448 foreach ( var pass
in effect.CurrentTechnique.Passes )
451 device.SamplerStates[0] = SamplerState.LinearClamp;
452 device.DrawUserPrimitives<VertexPositionColor>(
453 PrimitiveType.LineList,
454 pointVertices, 0, pointVertices.Length
static void DrawShape(Shape shape, ref Matrix transformation, ref Matrix textureTransformation, Image texture, Vector textureWrapSize, Color color)
Piirtää kuvion niin, että tekstuuri täyttää sen.
readonly Vector [] OutlineVertices
Ulkoreunan verteksit, lueteltuna vastapäivään.
readonly Vector [] Vertices
Kaikki verteksit, ml. kolmioiden kulmapisteet.
static readonly Color Black
Musta.
Microsoft.Xna.Framework.Vector2 XnaV2
static readonly Color Red
Punainen.
static void DrawImage(Image texture, ref Matrix matrix, Vector wrapSize)
static void DrawRaySegment(RaySegment segment, ref Matrix matrix, Color color)
readonly IndexTriangle [] Triangles
Kolmiot, joiden avulla kuvio voidaan täyttää värillä.
static void EndDrawingInsideShape()
Sisältää valmiiksi lasketut kolmiot, joiden avulla piirtäminen on suoraviivaista. ...
Peliluokka reaaliaikaisille peleille.
static new GraphicsDevice GraphicsDevice
static bool LightingEnabled
Luokka, joka sisältää metodeita kuvioiden ja tekstuurien piirtämiseen 2D-tasossa. ...
static void DrawShape(Shape shape, ref Matrix matrix, Color color)
static void DrawPolygon(Vector[] vertices, ref Matrix matrix, Color color)
Microsoft.Xna.Framework.Vector3 XnaV3
static readonly Color White
Valkoinen.
static void BeginDrawingInsideShape(Shape shape, ref Matrix transformation)
Makes all the subsequent draw calls until EndDrawingInsideShape limit the drawing inside shape (trans...