Ich schreibe ein Windows-Tool, das XNA verwendet und es dem Benutzer ermöglicht, Texturen auf dem Bildschirm zu platzieren.
Ich verwende eine 'Kamera' für das SpriteBatch, mit dem die Texturen gezeichnet werden, z.
Matrix matrixForSpriteBatch = Matrix.CreateTranslation(
-_cameraPosition.X, -_cameraPosition.Y, 0.0f) *
Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(_scale) *
Matrix.CreateTranslation(
GraphicsDevice.Viewport.Width / 2,
GraphicsDevice.Viewport.Height / 2, 0.0f);
Dies funktioniert einwandfrei - der Benutzer kann eine Textur auf die Leinwand legen und sie verschieben, drehen und in der Größe anpassen. Sie können die Kamera auch bewegen, um mehr Dinge zu sehen.
Was ich jetzt tun möchte, ist, die Benutzer herumklicken zu lassen, um Punkte eines Polygons zu definieren. Diese Punkte werden dann an meine DrawPolygonFilled
Methode gesendet :
public void DrawPolygonFilled( SpriteBatch spriteBatch,
Vector2[ ] worldPoints,
Color color )
{
Matrix matrixForVertices =
Matrix.CreateTranslation( _cameraPosition.X, -_cameraPosition.Y, 0.0f ) *
Matrix.CreateRotationZ( -rotation ) *
Matrix.CreateScale( camera.Scale ) ;
Vector2[] transformedPoints = worldPoints.Transform( matrixForVertices ) ;
var vertices = new VertexPositionColor[ transformedPoints.Length ] ;
for (int i = 0; i < transformedPoints.Length; i++)
{
vertices[ i ] = new VertexPositionColor( new Vector3( transformedPoints[ i ], 0 ), color ) ;
}
Vector2[ ] outputVertices ;
short[ ] outputIndicies ;
Vertices.Triangulate( transformedPoints, Vertices.WindingOrder.Clockwise, out outputVertices, out outputIndicies ) ;
if (outputIndicies.Length > 0)
{
foreach( EffectPass pass in _basicEffect.CurrentTechnique.Passes )
{
pass.Apply( ) ;
spriteBatch.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList,
vertices,
0,
vertices.Length,
outputIndicies,
0,
outputIndicies.Length /3 ) ;
}
}
}
Dies zeigt nichts an, da der Client-Speicherplatz BasicEffect
oben links 0,0 und unten rechts 1-1 beträgt. Also habe ich folgendes hinzugefügt zu BasicEffect
:
_basicEffect = new BasicEffect( GraphicsDevice )
{
VertexColorEnabled = true
} ;
_viewMatrix = Matrix.CreateLookAt(
new Vector3( 0, 0, GraphicsDevice.Viewport.Width ),
Vector3.Zero,
Vector3.Up
) ;
_projectionMatrix = Matrix.CreateOrthographic(
GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height,
.1f,
GraphicsDevice.Viewport.Width ) ;
_basicEffect.Projection = _projectionMatrix ;
_basicEffect.View = _viewMatrix ;
Damit wird das Polygon angezeigt, aber es steht auf dem Kopf. Wenn sich die Position des Polygons ändert (der Benutzer kann das Polygon mit der Maus ziehen), wird das Polygon nach oben verschoben, wenn der Benutzer die Maus nach unten bewegt!
Ich bin ein bisschen dick (aber ich versuche weniger dick zu werden), wenn es um Matrizen und Geometrie geht. Vermisse ich etwas Ich habe versucht, Down
zu Up
in zu wechseln , CreateLookAt
aber es wurde immer noch nicht richtig gezeichnet. Wenn der Benutzer die Maus verlässt, geht das Polygon nach rechts!
Hier ist ein Screenshot beim Zeichnen eines Polygons mit 0,0:
Die Punkte auf dem weißen Pfad sind die Stellen, an denen der Benutzer geklickt hat (und die mit SpriteBatch gezeichnet wurden), und das gelbe Polygon ist das, was mit meiner obigen Methode gezeichnet wurde.
Hier ist ein weiterer Screenshot, der zeigt, was passiert, wenn ich das Polygon auf 20,20 verschiebe:
Der weiße Pfad wird ab 20,20 gezeichnet, das gefüllte Polygon beginnt jedoch zwischen 20, -20 und wird verkehrt herum gezeichnet
Ich denke, dies ist ein Matrixproblem zwischen der Matrix, die von SpriteBatch
(zum Zeichnen der weißen Pfade) und der Matrix BasicEffect
(zum Zeichnen des gefüllten Polygons) verwendet wird.
SpriteBatch
. Weitere Informationen finden Sie unter den Links in meiner Antwort (und beachten Sie natürlich, dass dies für XNA und DirectX 9 gilt, nicht jedoch für DirectX 10 und OpenGL).Die in SpriteBatch verwendete Matrix wird mit Matrix.CreateOrthographicOffCenter erstellt:
Auf diese Weise behalten Sie Ihren Weltursprung in der oberen linken Ecke.
quelle