生成的地形不会在 directX 中显示(C#)

发布于 2024-09-13 04:27:56 字数 8742 浏览 5 评论 0原文

我用这个方程生成了

一个地形:

H(x,y) = (abs(sin(x * y)) + abs(sin(0,2 * x) + sin(0,4 * y)) + abs( cos(0,12 * x) + cos(0,47 * y))) * e^(0.005*(x+y))

现在,这给了我特征大小和漂亮斜率的组合。当我使用 scilab 绘制它时,效果很好。

我尝试将其导入到 ac# 应用程序中。

地形是用这段代码创建的:

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
using System.Collections.Generic;

namespace Kamera_eins
{

    public partial class Terrain : Form

    {
        public double[,] DTM;
        string response ;

        public Terrain()
        {

            InitializeComponent();
            response = "";
            DTM =  new double[2048/4,2048/4];


        }

        public void BoxTheSky()
        {


        }

        public void BoxTheLand()
        {

            mesh();

            surf();
        }
        public void begin()
        {

        }

        public void mesh()
        {
            response = "";
            int i = new int();
            int j = new int();
            i = 0;
            j = 0;

            for (i=0;i<2048/4 ;i++ ) {
                for (j=0;j<2048/4 ;j++ ) {
                    DTM[i,j] = Math.Abs (Math.Sin (j*i)) + Math.Abs(Math.Sin(0.2*i) * Math.Sin(0.4*j) ) + Math.Abs(Math.Cos(0.12* i) * Math.Cos(0.47*j));
                    DTM[i,j] = Math.Pow(Math.E, (0.012* (i + j)));


                }
            }

            response = "DTM  mesh ready"; 


        }

        public void surf()
        {

        }
    }
    }

它保存在一个名为terrain.cs的文件中,我将其设为winform,因为我计划添加一个简单的文本框,稍后我可以在其中制作某种过程的实时日志。

现在,有另一个文件,在该文件中,打算显示这个地形。第二个文件如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
using System.IO;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;


namespace Kamera_eins
{
    public class viewport : Form
    {
        public Microsoft.DirectX.Direct3D.Device device = null;
        public PresentParameters presentparameter = new PresentParameters();
        public bool device_exists;

        public bool show;

        public int HEIGHT;
        public int WIDTH;

        public string paintDesc;


        private float angle ;
        private CustomVertex.PositionColored[] vertices;
        public double[,] heightData;
        private int[] indices;
        private IndexBuffer ib;
        private VertexBuffer vb;
         private Microsoft.DirectX.DirectInput.Device keyb;

        //public 


        public viewport()
        {
            this.ClientSize = new System.Drawing.Size(600, 600);
            this.Text = "Terrain viewport";

            WIDTH = 2048 / 4;
            HEIGHT = 2048 / 4;

            heightData = new double[HEIGHT,WIDTH];


            keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
             keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
             keyb.Acquire();

            presentparameter.Windowed = true;
            presentparameter.SwapEffect = SwapEffect.Discard;
            presentparameter.AutoDepthStencilFormat = DepthFormat.D16;
            presentparameter.EnableAutoDepthStencil = true;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

            try {

            device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentparameter);
            device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);
            device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);
            device.Disposing += new EventHandler(this.DeleteDeviceObjects);
            device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);

            device_exists = true;


            } catch (Exception DirectException) {
            device_exists = false;  
            }



        }

        private void setcamera()
        {
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1f, 50f);
            device.Transform.View = Matrix.LookAtLH (new Vector3(0, 0, 100), new Vector3(0, 0, 0) , new Vector3(0,0,1) );
            device.RenderState.Lighting = false;
            device.RenderState.FillMode = FillMode.WireFrame;
            device.RenderState.CullMode = Cull.None;
        }


        public void declareVertex()
        {
            vb = new VertexBuffer(typeof(CustomVertex.PositionColored), HEIGHT*WIDTH, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
            vertices = new CustomVertex.PositionColored[HEIGHT*WIDTH];

            for (int x=0;x< WIDTH;x++)            {

                for (int y=0; y< HEIGHT;y++)                {
                    vertices[x + y * WIDTH].Position = new Vector3(x, y, (float)heightData[x,y]);
                    int r = Convert.ToInt32(205 * heightData[x,y] / 200 );
                    if(r>254)
                        r = 254;

                    vertices[x + y * WIDTH].Color =  Color.FromArgb( r , 120 , 120).ToArgb();

                }
            }

            vb.SetData(vertices, 0, LockFlags.None);

        }

        public void declareIndex()
        {
            ib = new IndexBuffer(typeof(int), (WIDTH-1)*(HEIGHT-1)*6, device, Usage.WriteOnly, Pool.Default);
            indices = new int[(WIDTH-1)*(HEIGHT-1)*6];

            for (int x=0;x< WIDTH-1;x++)            {

                for (int y=0; y< HEIGHT-1;y++)                {
                    indices[(x+y*(WIDTH-1))*6] = (x+1)+(y+1)*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+1] = (x+1)+y*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+2] = x+y*WIDTH;

                    indices[(x+y*(WIDTH-1))*6+3] = (x+1)+(y+1)*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+4] = x+y*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+5] = x+(y+1)*WIDTH;
                }
            }
            ib.SetData(indices, 0, LockFlags.None);
        }



         protected override void Dispose (bool disposing)
         {

             base.Dispose(disposing);
             MessageBox.Show("");
         }


        protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void RestoreDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void DeleteDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)
        {
        }

        public void run()
        {
            while(this.Created)
            {
                render();
                setcamera();


                // optional: loading the height using functional call:
                //  loadheight();

                Application.DoEvents();
            }
        }


        public void render()
        {
            if (device != null)
            {
                device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
                device.BeginScene();

                //display terrain
                device.VertexFormat = CustomVertex.PositionColored.Format;
            device.SetStreamSource(0, vb, 0);
            device.Indices = ib;

            device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0)*Matrix.RotationZ(angle) ;
            device.DrawIndexedPrimitives(PrimitiveType.TriangleFan, 0, 0, WIDTH*HEIGHT, 0, indices.Length/3);






                //turn off lights now

                device.EndScene();
                device.Present();
                this.Invalidate();
                readkeyboard();

            }
        }

        void readkeyboard()
        {

             KeyboardState keys = keyb.GetCurrentKeyboardState();
            if (keys[Key.Delete])
            {
                angle+=0.03f;
            }
            if (keys[Key.Next])
            {
                angle-=0.03f;
            }
        }

        public void openport()
        {




        }



            protected override void OnPaint(PaintEventArgs e)
        {


                render();
                setcamera();

        }


    }
}

现在,第三个文件调用世界创建和显示:

void MainFormLoad(object sender, EventArgs e)
        {
            world = new World();
            world.setterrain();
}

surf 和 box-somthing 函数尚未执行任何操作。

我现在得到的只是一个黑色窗口(device.clear(...) 部分)-我尝试调整相机..没有成功

请帮助,我想在窗口中显示地形....

Greetings

I genereated a terrain with this equation:

H(x,y) = (abs(sin(x * y)) + abs(sin(0,2 * x) + sin(0,4 * y)) + abs(cos(0,12 * x) + cos(0,47 * y))) * e^(0.005*(x+y))

Now, this gives me a mix of featuresize, and a nice slope. This works fine, when I plot it using scilab.

I tried to import this in a c# application.

The terrain is created in this code:

using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX;
using System.Collections.Generic;

namespace Kamera_eins
{

    public partial class Terrain : Form

    {
        public double[,] DTM;
        string response ;

        public Terrain()
        {

            InitializeComponent();
            response = "";
            DTM =  new double[2048/4,2048/4];


        }

        public void BoxTheSky()
        {


        }

        public void BoxTheLand()
        {

            mesh();

            surf();
        }
        public void begin()
        {

        }

        public void mesh()
        {
            response = "";
            int i = new int();
            int j = new int();
            i = 0;
            j = 0;

            for (i=0;i<2048/4 ;i++ ) {
                for (j=0;j<2048/4 ;j++ ) {
                    DTM[i,j] = Math.Abs (Math.Sin (j*i)) + Math.Abs(Math.Sin(0.2*i) * Math.Sin(0.4*j) ) + Math.Abs(Math.Cos(0.12* i) * Math.Cos(0.47*j));
                    DTM[i,j] = Math.Pow(Math.E, (0.012* (i + j)));


                }
            }

            response = "DTM  mesh ready"; 


        }

        public void surf()
        {

        }
    }
    }

This is kept in a file called terrain.cs, and i make this a winform, because i plan to add a simple textbox, where i can later make some sort of realtime log of the process.

Now, there is another file, and in that file, intend to display this terrain. this second file goes as follows:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Data;
using System.IO;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;


namespace Kamera_eins
{
    public class viewport : Form
    {
        public Microsoft.DirectX.Direct3D.Device device = null;
        public PresentParameters presentparameter = new PresentParameters();
        public bool device_exists;

        public bool show;

        public int HEIGHT;
        public int WIDTH;

        public string paintDesc;


        private float angle ;
        private CustomVertex.PositionColored[] vertices;
        public double[,] heightData;
        private int[] indices;
        private IndexBuffer ib;
        private VertexBuffer vb;
         private Microsoft.DirectX.DirectInput.Device keyb;

        //public 


        public viewport()
        {
            this.ClientSize = new System.Drawing.Size(600, 600);
            this.Text = "Terrain viewport";

            WIDTH = 2048 / 4;
            HEIGHT = 2048 / 4;

            heightData = new double[HEIGHT,WIDTH];


            keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
             keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
             keyb.Acquire();

            presentparameter.Windowed = true;
            presentparameter.SwapEffect = SwapEffect.Discard;
            presentparameter.AutoDepthStencilFormat = DepthFormat.D16;
            presentparameter.EnableAutoDepthStencil = true;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);

            try {

            device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentparameter);
            device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);
            device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);
            device.Disposing += new EventHandler(this.DeleteDeviceObjects);
            device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);

            device_exists = true;


            } catch (Exception DirectException) {
            device_exists = false;  
            }



        }

        private void setcamera()
        {
            device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1f, 50f);
            device.Transform.View = Matrix.LookAtLH (new Vector3(0, 0, 100), new Vector3(0, 0, 0) , new Vector3(0,0,1) );
            device.RenderState.Lighting = false;
            device.RenderState.FillMode = FillMode.WireFrame;
            device.RenderState.CullMode = Cull.None;
        }


        public void declareVertex()
        {
            vb = new VertexBuffer(typeof(CustomVertex.PositionColored), HEIGHT*WIDTH, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
            vertices = new CustomVertex.PositionColored[HEIGHT*WIDTH];

            for (int x=0;x< WIDTH;x++)            {

                for (int y=0; y< HEIGHT;y++)                {
                    vertices[x + y * WIDTH].Position = new Vector3(x, y, (float)heightData[x,y]);
                    int r = Convert.ToInt32(205 * heightData[x,y] / 200 );
                    if(r>254)
                        r = 254;

                    vertices[x + y * WIDTH].Color =  Color.FromArgb( r , 120 , 120).ToArgb();

                }
            }

            vb.SetData(vertices, 0, LockFlags.None);

        }

        public void declareIndex()
        {
            ib = new IndexBuffer(typeof(int), (WIDTH-1)*(HEIGHT-1)*6, device, Usage.WriteOnly, Pool.Default);
            indices = new int[(WIDTH-1)*(HEIGHT-1)*6];

            for (int x=0;x< WIDTH-1;x++)            {

                for (int y=0; y< HEIGHT-1;y++)                {
                    indices[(x+y*(WIDTH-1))*6] = (x+1)+(y+1)*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+1] = (x+1)+y*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+2] = x+y*WIDTH;

                    indices[(x+y*(WIDTH-1))*6+3] = (x+1)+(y+1)*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+4] = x+y*WIDTH;
                    indices[(x+y*(WIDTH-1))*6+5] = x+(y+1)*WIDTH;
                }
            }
            ib.SetData(indices, 0, LockFlags.None);
        }



         protected override void Dispose (bool disposing)
         {

             base.Dispose(disposing);
             MessageBox.Show("");
         }


        protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void RestoreDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void DeleteDeviceObjects(object sender, EventArgs e)
        {
        }

        protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)
        {
        }

        public void run()
        {
            while(this.Created)
            {
                render();
                setcamera();


                // optional: loading the height using functional call:
                //  loadheight();

                Application.DoEvents();
            }
        }


        public void render()
        {
            if (device != null)
            {
                device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
                device.BeginScene();

                //display terrain
                device.VertexFormat = CustomVertex.PositionColored.Format;
            device.SetStreamSource(0, vb, 0);
            device.Indices = ib;

            device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0)*Matrix.RotationZ(angle) ;
            device.DrawIndexedPrimitives(PrimitiveType.TriangleFan, 0, 0, WIDTH*HEIGHT, 0, indices.Length/3);






                //turn off lights now

                device.EndScene();
                device.Present();
                this.Invalidate();
                readkeyboard();

            }
        }

        void readkeyboard()
        {

             KeyboardState keys = keyb.GetCurrentKeyboardState();
            if (keys[Key.Delete])
            {
                angle+=0.03f;
            }
            if (keys[Key.Next])
            {
                angle-=0.03f;
            }
        }

        public void openport()
        {




        }



            protected override void OnPaint(PaintEventArgs e)
        {


                render();
                setcamera();

        }


    }
}

Now, yet a third file calls the world creation and display:

void MainFormLoad(object sender, EventArgs e)
        {
            world = new World();
            world.setterrain();
}

the surf and box-somthing functions do not yet do anything.

All what i get now, is just a black window (the device.clear(... ) part) - i tried to adjust the camera .. no success

please help, i want to show the terrain in the window ....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文