XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 Account settings
  Posted by: Anonymous
  When: 07/05/2014 at 09:48:39

 forced subtitle
  Posted by: Applefly
  When: 07/05/2014 at 06:00:48

 convert DVD into PMS
  Posted by: Applefly
  When: 07/05/2014 at 05:55:25

 DVD to Digital Copy easily
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:52:29

 DVD on Xbox 360/Xbox One Console
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:51:47

 Extract .Srt Subtitles
  Posted by: Applefly
  When: 04/05/2014 at 03:54:38

 Encode Movie collection
  Posted by: Applefly
  When: 04/05/2014 at 03:52:41

 Convert DVD to WMV
  Posted by: Applefly
  When: 29/04/2014 at 05:53:50

 rip DVDs into digital files
  Posted by: Applefly
  When: 29/04/2014 at 05:51:20

 iTunes movies/music to Kindle Fire
  Posted by: ciciyu80
  When: 29/04/2014 at 05:10:20


Ads

Terrain creation from file

It's time to finally create a nice looking landscape. Instead of manually entering the HeightData array, we are going to fill it from a file. To do this, we are going to load a 64x64 black&white image, and use the 'white value' of every pixel as the Z coordinate for the corresponding pixel! You can download my example file here (link). To open and read files, you need to add the following line to your using-block :

 using System.IO;

Change your LoadHeightData method to this:

 private void LoadHeightData()
 {
     heightData = new int[WIDTH,HEIGHT];
  
     FileStream fs = new FileStream("heightdata.raw",FileMode.Open, FileAccess.Read);
     BinaryReader r = new BinaryReader(fs);

    for (int i = 0;i< HEIGHT;i++)    {

        for (int y=0; y< WIDTH; y++)        {
            int height =(int)(r.ReadByte()/50);
            heightData[WIDTH-1-y,HEIGHT-1-i] = height;
        }
    }
    r.Close();
}

First we create a heightData array capable of storing the 64x64 Z coordinates. The 2 following lines open the file heightdata.raw that should be in the same directory as your .exe file for binary access. In a .raw file, the 'white value' of every pixel is stored byte after byte. So the only thing we have to do is load byte after byte into our heightData array! We divide by 50, otherwise the Z coordinates would be way too high. We have to use the WIDTH-1-y structures, because the data is stored inversely in the .raw format. Now change our width and height variables so we can display the whole terrain :

 private int WIDTH = 64;
 private int HEIGHT = 64;

You can try running this code, but you'll notice that you can't see the whole terrain with our current camera settings. First we'll introduce a translation before drawing the triangles, so the middle of the terrain is in the (0,0,0) position. Add the following line immediately before you call the DrawIndexedPrimitives method:

 device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0);

With the terrain in the center of our window, the only thing left to do is reposition our camera!

 device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4, this.Width/this.Height, 1f, 150f);
 device.Transform.View = Matrix.LookAtLH(new Vector3(0,-40,50), new Vector3(0,-5,0), new Vector3(0,1,0));

Don't forget to set the far clipping plane to 150f or the points further than 50 units away from the camera won’t be drawn! Just set the background color to black to have a nicer result. Now run the program and you'll see a nice terrain :-)




DirectX Tutorial 8 - Terrain from file

If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



Click here to go to the forum on this chapter!

Or click on one of the topics on this chapter to go there:
  • Flat Terrain
          Howdy. These are by far some of the best tutorials...
  • multiple terrains
          Hi, Great tutorials thanks. I am writing a 3d C...
  • Error in Indices Loop Code?
          I'm somewhat of a DirectX noob, although I have t...
  • Unexpected triangles being drawn
          Hi! The basic code of this tutorial worked fine...
  • Reading .raw error
          When I put the heighdata.raw file in my debug fold...
  • windows is dark
          I run the code of terrain from file but the window...
  • About Terrain from file
          Hello everyone ..Thanks a Lot Mr.Riemer for ur coo...
  • Editor .raw files
          How i can edit .raw file? I want change terrain, b...
  • Dont get indices to work at all
          Hi! Liked your tutorial it was verry easy to gras...
  • Problems with the debug
          hi when i debug (f5) the program this have so tro...
  • Window Resize
          I tired both the printed code copied and pasted an...
  • "Error in the application"
          Hi! When I use F6 “Build Solution” no problems ...



    Here's the total code:

     using System;
     using System.Drawing;
     using System.Collections;
     using System.ComponentModel;
     using System.Windows.Forms;
     using System.Data;
     using Microsoft.DirectX;
     using Microsoft.DirectX.Direct3D;
     using System.IO;
      
     namespace DirectX_Tutorial
     {
      
         public class WinForm : System.Windows.Forms.Form
         {
             private int WIDTH = 64;
             private int HEIGHT = 64;
             private Device device;
             private System.ComponentModel.Container components = null;
             private float angle = 0f;
             private CustomVertex.PositionColored[] vertices;
             private int[,] heightData;
             private int[] indices;
             private IndexBuffer ib;
             private VertexBuffer vb;
      
             public WinForm()
             {
                 InitializeComponent();
                 this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
             }
      
             public void InitializeDevice()
             {
                 PresentParameters presentParams = new PresentParameters();
                 presentParams.Windowed = true;
                 presentParams.SwapEffect = SwapEffect.Discard;
                 device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
                 device.RenderState.FillMode = FillMode.WireFrame;
                 device.RenderState.CullMode = Cull.None;
             }
      
             private void CameraPositioning()
             {
                 device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI/4, this.Width/this.Height, 1f, 150f);
                 device.Transform.View = Matrix.LookAtLH(new Vector3(0,-40,50), new Vector3(0,-5,0), new Vector3(0,1,0));
                 device.RenderState.Lighting = false;
                 device.RenderState.CullMode = Cull.None;
             }
      
             private void VertexDeclaration()
             {
                 vb = new VertexBuffer(typeof(CustomVertex.PositionColored), WIDTH*HEIGHT, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
                 vertices = new CustomVertex.PositionColored[WIDTH*HEIGHT];

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

                    for (int y=0; y< HEIGHT;y++)                {
                        vertices[x+y*WIDTH].Position = new Vector3(x, y, heightData[x,y]);
                        vertices[x+y*WIDTH].Color = Color.White.ToArgb();
                    }
                }
     
                vb.SetData(vertices, 0 ,LockFlags.None);
            }
     
            private void IndicesDeclaration()
            {
                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 OnPaint(System.Windows.Forms.PaintEventArgs e)
            {
                device.Clear(ClearFlags.Target, Color.Black , 1.0f, 0);
     
                device.BeginScene();
                device.VertexFormat = CustomVertex.PositionColored.Format;
                device.SetStreamSource(0, vb, 0);
                device.Indices = ib;
     

                 device.Transform.World = Matrix.Translation(-HEIGHT/2, -WIDTH/2, 0);
                 device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, WIDTH*HEIGHT, 0, indices.Length/3);
                 device.EndScene();
      
                 device.Present();
      
                 this.Invalidate();
                 angle += 0.05f;
             }
      
             private void LoadHeightData()
             {
                 heightData = new int[WIDTH,HEIGHT];
      
                 FileStream fs = new FileStream("heightdata.raw",FileMode.Open, FileAccess.Read);
                 BinaryReader r = new BinaryReader(fs);

                for (int i = 0;i< HEIGHT;i++)            {

                    for (int y=0; y< WIDTH; y++)                {
                        int height =(int)(r.ReadByte()/50);
                        heightData[WIDTH-1-y,HEIGHT-1-i] = height;
                    }
                }
                r.Close();
            }
     

             protected override void Dispose (bool disposing)
             {
                 if (disposing)
                 {
                     if (components != null)
                     {
                         components.Dispose();
                     }
                 }
                 base.Dispose(disposing);
             }
      
             private void InitializeComponent()
             {
                 this.components = new System.ComponentModel.Container();
                 this.Size = new System.Drawing.Size(500,500);
                 this.Text = "DirectX Tutorial";
             }
     
             static void Main()
             {
                 using (WinForm our_directx_form = new WinForm())
                 {
                     our_directx_form.LoadHeightData();
                     our_directx_form.InitializeDevice();
                     our_directx_form.CameraPositioning();
                     our_directx_form.VertexDeclaration();
                     our_directx_form.IndicesDeclaration();
                     our_directx_form.Show();
                     Application.Run(our_directx_form);
                 }
             }
         }
     }
     


    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2011 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2011 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    XNA 3.0 Recipes Book (8)
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Tutorials (160)
    XNA 4.0 using C# (89)
    DirectX using C# (54)
    Series 1:Terrain (14)
    Opening a window
    Linking to the Device
    Drawing a triangle
    Camera
    Rotation - Translation
    Indices
    Terrain creation
    Terrain from file
    DirectInput
    Importing bmp files
    Colored vertices
    DirectX Light basics
    Mesh creation
    Mesh lighting
    Series 2: Flightsim (19)
    Series 3: HLSL (19)
    Short Tuts (2)
    DirectX using C++ (15)
    DirectX using VB (2)
    -- Expand all --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!