Sign in to follow this  

[MDX] Almost there....

This topic is 4267 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am oh so close to getting my first terrain rendered, I can feel it. Problem is, I get a GraphicsException thrown when I call Present(), which, after looking on MSDN, I found is far too general to be much help to me. I was hoping some of you MDX gurus could take a look at my code and tell me what's up. I've tried to eliminate what I feel is irrelevant code, but I also want to make sure the code that matters is there, so I apologize if there is a bit too much code. Anyway, here it is:
namespace TerrainGen
{
    public partial class Visualize : Form
    {
        Device device = null;
        VertexBuffer vb = null;
        IndexBuffer ib = null;
        PresentParameters pp = new PresentParameters();
        CustomVertex.PositionNormal[] verts;
        int[] indices;
        short x, y;

        public Visualize()
        {
            InitializeComponent();
        }

        private void Visualize_Load(object sender, EventArgs e)
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
            InitGFX();
            LoadVertexBufferLOT();
            LoadIndexBuffer();
        }

        public void InitGFX()
        {
            pp.Windowed = true;
            pp.SwapEffect = SwapEffect.Discard;
            pp.AutoDepthStencilFormat = DepthFormat.D16;
            pp.EnableAutoDepthStencil = true;

            device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, pp);

            device.RenderState.FillMode = FillMode.WireFrame;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
            device.Present();
            this.Invalidate();
        }

        private void LoadVertexBufferLOT()
        {
            StreamReader reader = new StreamReader("temp.lot");

            x = Int16.Parse(reader.ReadLine());
            y = Int16.Parse(reader.ReadLine());

            verts = new CustomVertex.PositionNormal[x * y];

            for (int i = 0; i < y; i++)
            {
                for (int n = 0; n < x; n++)
                {
                    verts[n * i].Nx = 0;
                    verts[n * i].Ny = 1;
                    verts[n * i].Nz = 0;
                    verts[n * i].Position = new Vector3((float)n, float.Parse(reader.ReadLine()), (float)i);
                }
            }

            reader.Close();

            ComputeNormals();

            vb = new VertexBuffer(typeof(CustomVertex.PositionNormal), x*y, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionNormal.Format, Pool.Default);
            vb.SetData(verts, 0, LockFlags.None);

        }

        private void ComputeNormals()
        {
            for (int i = 1; i < y - 1; i++)
            {
                for (int n = 1; n < x - 1; n++)
                {
                    Vector3 X = Vector3.Subtract(verts[i * (y - 1) + n + 1].Position, verts[i * (y - 1) + n - 1].Position);
                    Vector3 Z = Vector3.Subtract(verts[(i + 1) * (y - 1) + n].Position, verts[(i - 1) * (y - 1) + n].Position);
                    Vector3 Normal = Vector3.Cross(Z, X);
                    Normal.Normalize();
                    verts[n * i].Normal = Normal;
                }
            }
        }

        private void LoadIndexBuffer()
        {
            indices = new int[(x * y * 6)];
            int i = 0;
            for (int b = 0; b < y - 1; b++)
            {
                for (int n = 0; n < x - 1; n++)
                {
                    indices[i] = b * x + n;
                    indices[i + 1] = b * x + n + 1;
                    indices[i + 2] = (b + 1) * x + n;
                    indices[i + 3] = (b + 1) * x + n;
                    indices[i + 4] = b * x + n + 1;
                    indices[i + 5] = (b + 1) * x + n + 1;

                    i += 6;
                }
            }

            ib = new IndexBuffer(typeof(int), indices.Length, device, Usage.WriteOnly, Pool.Default);
            ib.Created += new EventHandler(this.OnIndexBufferCreate);
            OnIndexBufferCreate(ib, null);
        }

        private void OnIndexBufferCreate(object sender, EventArgs e)
        {
            IndexBuffer buffer = (IndexBuffer)sender;
            buffer.SetData(indices, 0, LockFlags.None);
        }

        private void SetupCamera()
        {
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 3000.0f);
            device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 5.0f), new Vector3(), new Vector3(0, 1, 0));
        }

        public void Render()
        {
            device.BeginScene();
            device.VertexFormat = CustomVertex.PositionNormal.Format;
            device.SetStreamSource(0, vb, 0);
            device.Indices = ib;
            device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, x * y, 0, indices.Length / 3);
            device.EndScene();
            device.Present();
        }
    }
}

And if it helps, this takes place in a child window of my main form for which the code in the main form is:
using (Visualize vis = new Visualize())
{
    vis.ShowDialog();
    while (!vis.Disposing)
    {
        vis.Render();
    }
}
Thanks. -AJ

Share this post


Link to post
Share on other sites
Usually some of the problems I see with rendering to child windows is the handle not being passed. Try and pass this.Handle or control.Handle.

Also make sure that your device isn't lost. You aren't catching any exceptions which brings me to believe that the device has been lost. Mostly this is the exception that is thrown from the Present() method.

Take a look at Lost Devices from the DirectX Documentation.

I hope this helps a bit.
Take care.

Share this post


Link to post
Share on other sites
So it seems that if I move all my rendering code into my OnPaint override then it compiles and runs fine (an by that I mean, actually draw something). I'll have to play around with it I guess to get it to draw what I want it draw. Anyway, any particular reason it works when I put it in the OnPaint override rather than calling the render function seperately? Thanks.

-AJ

Share this post


Link to post
Share on other sites

This topic is 4267 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this