在3d世界的动态2d渲染

时间:2014-05-30 21:35:33

标签: xna drawing

好的,所以我正在使用我在XNA的第一次认真经验。这是我当前的任务:下载文件。从该文件解析一个"形状的列表。"每个"形状"包含一个点列表。这些点是要在地图上绘制的线条的顶点。事实上,它是整个美国的县地图,所以"形状的数量"不是微不足道的。我们需要能够放大和缩小此地图,因此需要在3d空间中进行二维渲染。我想知道最好的策略是什么。

我尝试过简单地使用DrawUserIndexedPrimitives,但是绘制函数需要花费太长时间来处理它。

然后我想我会尝试在LoadContent中绘制一系列RenderTarget2D,并在Draw函数中保存这些纹理以进行绘制。但到目前为止,我似乎得到的只是一系列紫色盒子。

编辑:

这是我目前的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Runtime.InteropServices;



namespace First
{
class FirstShape : DrawableGameComponent
{
    const int kSizeMultiplier = 10;

    public FirstShape(string inFilePath, Game inGame) : base(inGame)
    {
        DrawOrder = 1000;
        mFile = inFilePath;
    }



    protected override void LoadContent()
    {
        mSpriteBatch = new SpriteBatch(GraphicsDevice);

        FirstMemoryStream stream = FirstMemoryStream.MakeSeekableStream(File.OpenRead(mFile));

        // skip headers
        stream.Seek(100, 0);

        for (int i = 0; stream.Position != stream.Length; i++)
        {
            stream.Seek(stream.Position + 12, 0);

            double minX = stream.ReadDouble();
            double minY = stream.ReadDouble();
            double maxX = stream.ReadDouble();
            double maxY = stream.ReadDouble();
            int numParts = stream.ReadInt();
            int numPoints = stream.ReadInt();

            VertexPositionColor[] points = new VertexPositionColor[numPoints];

            stream.Seek(stream.Position + (4 * numParts), 0);

            int top, bottom, left, right;

            float x2, y2;
            x2 = (float)stream.ReadDouble();
            y2 = (float)stream.ReadDouble();

            Vector2 projectedPoint = Vertex(x2, y2);

            left = right = (int)Math.Round(projectedPoint.X * kSizeMultiplier);
            top = bottom = (int)Math.Round(maxY - (projectedPoint.Y * kSizeMultiplier));

            points[0].Position.X = left;
            points[0].Position.Y = top;

            for (int j = 1; j < points.Length; j++)
            {
                float x1 = x2;
                float y1 = y2;

                x2 = (float)stream.ReadDouble();
                y2 = (float)stream.ReadDouble();

                Vector2 p1 = Vertex(x1, y1);
                Vector2 p2 = Vertex(x2, y2);

                p1.X *= kSizeMultiplier;
                p1.Y *= kSizeMultiplier;
                p2.X *= kSizeMultiplier;
                p2.Y *= kSizeMultiplier;

                points[j].Position.X = (int)Math.Round(p2.X);
                points[j].Position.Y = (int)Math.Round(maxY - p2.Y);

                if (points[j].Position.X < left)
                    left = (int)points[j].Position.X;
                if (points[j].Position.X > right)
                    right = (int)points[j].Position.X;
                if (points[j].Position.Y < top)
                    top = (int)points[j].Position.Y;
                if (points[j].Position.Y > bottom)
                    bottom = (int)points[j].Position.Y;
            }

            if (mTopLeft.X == 0 || mTopLeft.X > left)
                mTopLeft.X = left;
            if (mTopLeft.Y == 0 || mTopLeft.Y > top)
                mTopLeft.Y = top;

            for (int j = 0; j < points.Length; j++)
            {
                points[j].Color = Color;
            }

            int width = (right - left) + 1;
            int height = (bottom - top) + 1;

            mTextures.Add(new FirstImage(GraphicsDevice, width, height, new Vector2(left, top)));

            GraphicsDevice.SetRenderTarget(mTextures.Last());
            GraphicsDevice.Indices = new IndexBuffer(GraphicsDevice, IndexElementSize.SixteenBits, points.Length, BufferUsage.None);
            GraphicsDevice.SetVertexBuffer(new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, points.Length, BufferUsage.None));

            BasicEffect basicEffect = new BasicEffect(GraphicsDevice);
            basicEffect.LightingEnabled = false;
            basicEffect.VertexColorEnabled = true;

            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();

                GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.LineStrip, 0, 0, points.Length, 0, points.Length - 1);
            }
        }

        GraphicsDevice.SetRenderTarget(null);

        stream.Close();

        for (int i = 0; i < mTextures.Count; i++)
        {
            mTextures[i].Position -= mTopLeft;
        }

    }



    public override void Draw(GameTime inTime)
    {
        mSpriteBatch.Begin();

        for(int i = 0; i < mTextures.Count; i++)
        {
            mSpriteBatch.Draw(mTextures[i], mTextures[i].Position, Color.White);
        }

        mSpriteBatch.End();
    }



    private Vector2 Vertex(float inX, float inY)
    {
       return FirstProjector.Project(new Vector2(inX, inY));
    }



    public Color Color { get; set; }



    private string mFile;
    private List<FirstImage> mTextures = new List<FirstImage>();

    private SpriteBatch mSpriteBatch;
    private Vector2 mTopLeft = new Vector2(0.0f, 0.0f);
    private Vector2 mBottomRight = new Vector2(0.0f, 0.0f);
}



class FirstImage : RenderTarget2D
{
    public FirstImage(GraphicsDevice inDevice, int inWidth, int inHeight, Vector2 inPosition) : base(inDevice, inWidth, inHeight, false, SurfaceFormat.Color, DepthFormat.None)
    {
        Position = inPosition;
    }
    public Vector2 Position {get; set;}
}

}

0 个答案:

没有答案