XNA: nevyklreslení výškové mapy   otázka

C#, XNA

Ahoj,

zkouším pomocí tutoriálu na tomto webu (http://vbnet.cz/clanek--77-xna_2_0_ve_vb... vykreslit výškovou mapu. Dělám ale v CSharp, tak jsem si vše pomocí konvertotu z vb.net převedo do c#.

Aplikace se spustí, žádná chyba tam není, ale výšková mapa (jako je na obrázku u tutoriálu) nelze vidět.

Nemáte tušení, kde bych měl pátrat?

Děkuji

nahlásit spamnahlásit spam 0 odpovědětodpovědět

doplňuji kód:

Game1.cs

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace WindowsGame1
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        private Landscape land;
        private Matrix world = Matrix.Identity;
        private Matrix view = Matrix.CreateLookAt(new Vector3(32, 80, 64), new Vector3(32, 0, 32), Vector3.Up);
        private Matrix proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 4 / 3, 1, 1000);

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            land = new Landscape(this.GraphicsDevice);
            land.LoadTerrain(Content.Load<Texture2D>("a"), 25);
            land.texture = Content.Load<Texture2D>("a");
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            land.Draw(world, view, proj);

            base.Draw(gameTime);
        }
    }
}

Landscape.cs:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace WindowsGame1
{
    internal class Landscape
    {
        private float[,] heights;
        private int verticesCount;
        private int indicesCount;
        private int width;
        private int height;

        private GraphicsDevice device;
        private VertexBuffer vb;
        private IndexBuffer ib;
        private BasicEffect effect;

        public Landscape(GraphicsDevice graphics)
        {
            device = graphics;
            effect = new BasicEffect(device, null);
        }

        public Texture2D texture
        {
            get;
            set;
        }

        public void LoadTerrain(Texture2D tex, double heightScale)
        {
            width = tex.Width;
            height = tex.Height;
            heights = new float[width, height];
            Color[] b = new Color[width * height];
            tex.GetData<Color>(b);
            for (int y = 0; y <= height - 1; y++)
            {
                for (int x = 0; x <= width - 1; x++)
                {
                    var _with1 = b[x + y * width];
                    heights[x, y] = (int)(heightScale / 255 * (Convert.ToDouble(_with1.R) + Convert.ToDouble(_with1.G) + Convert.ToDouble(_with1.B)) / 3);
                }
            }
            PrepareVertexBuffer();
            PrepareIndexBuffer();
        }

        private void PrepareVertexBuffer()
        {
            verticesCount = width * height;
            vb = new VertexBuffer(device, typeof(VertexPositionTexture), verticesCount, BufferUsage.WriteOnly);
            VertexPositionTexture[] verts = new VertexPositionTexture[verticesCount];
            for (int y = 0; y <= height - 1; y++)
            {
                for (int x = 0; x <= width - 1; x++)
                {
                    var _with1 = verts[x + y * width];
                    _with1.Position = new Vector3(x, heights[x, y], y);
                }
            }
            vb.SetData<VertexPositionTexture>(verts);
        }

        private void PrepareIndexBuffer()
        {
            indicesCount = (width - 1) * (height - 1) * 6;
            ib = new IndexBuffer(device, typeof(int), indicesCount, BufferUsage.WriteOnly);
            int[] indices = new int[indicesCount];
            int k = 0;
            for (int y = 0; y <= height - 2; y++)
            {
                for (int x = 0; x <= width - 2; x++)
                {
                    int b = x + y * width;
                    indices[k] = b;
                    indices[k + 1] = b + 1;
                    indices[k + 2] = b + 1 + width;
                    indices[k + 3] = b;
                    indices[k + 4] = b + 1 + width;
                    indices[k + 5] = b + width;
                    k += 6;
                }
            }
            ib.SetData<int>(indices);
        }

        public void Draw(Matrix world, Matrix view, Matrix proj)
        {
            effect.World = world;
            effect.View = view;
            effect.Projection = proj;
            device.RenderState.FillMode = FillMode.WireFrame;
            effect.Begin(SaveStateMode.None);
            effect.TextureEnabled = true;
            effect.Texture = texture;
            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Begin();
                device.VertexDeclaration = new VertexDeclaration(device, VertexPositionTexture.VertexElements);
                device.Vertices[0].SetSource(vb, 0, VertexPositionTexture.SizeInBytes);
                device.Indices = ib;
                device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, verticesCount, 0, indicesCount / 3);
                pass.End();
            }
            effect.End();
        }
    }
}

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Těch příčin tu může být více, špatně se to ladí, ale doporučuju se podívat na následující:

1) Ověřit, že ve vertex a index bufferu opravdu jsou hodnoty, nejlépe debuggerem na konci těch funkcí, které je staví.

2) Ujistit se, že máte správně nastavené pozice a směr kamery a nekoukáte jinam.

3) Zkuste ještě nastavit CullMode na None - kvůli optimalizacím se standardně vykreslují jen trojúhelníky, které nejsou odvrácené od kamery (definuje se to podle pořadí vertexů).

Zkuste do funkce Draw přidat tohle před volání effect.Begin();

         RasterizerState rs = new RasterizerState();
         rs.CullMode = CullMode.None;
         device.RasterizerState = rs;

Nemám tu VS 2010, takže to nemůžu vyzkoušet.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback