Click here to Skip to main content
Click here to Skip to main content

3D Terrain Visualisation in Managed DirectX 9 and C#

By , 18 Sep 2005
 

Point, Wireframe and Solid (Textured) Mode

Introduction

GIS (Geographical Information System) is a computer support system that represents data using maps. It helps people access, display and analyse data that has geographic content and meaning. For those not familiar with GIS, it used to be a niche IT market dominated by the traditional GIS and CAD companies such as Intergraph, Bentley, MapInfo, Autodesk and ESRI. Nowadays global IT giants such as Microsoft, Google and Oracle are competing for their share of the pie through products such as Virtual Earth, Google Earth and Oracle Spatial. NASA has also recently released a free, open source GIS viewer application called World Wind.

In this article, I will demonstrate how to build a standalone 3D terrain visualisation tool from scratch using C# and Managed DirectX 9.0c. The application will allow the user to rotate the point of view using the arrow keys and to change the rendering mode to (P) Point, (W) Wire frame and (S) Solid.

Background

I recently completed a GIS system implementation for a local City Council. During that project I developed a proof of concept application to demonstrate the technical feasibility of 3D visualisation using the available spot heights and aerial photography textures. The aim of this article is to share my knowledge and experience with all developers interested in GIS and .NET.

Requirements

Before we start, I would like to specify the software requirements for this project:

  • Visual Studio .NET IDE (I used 2005 beta 2)
  • Managed DirectX 9.0c SDK (I used August 2005 update)
  • .NET framework (I used v2.0 but v1.1 will work as well)

3D rendering concepts

First of all I will need to explain the general 3D programming concepts behind my code. Unfortunately, entire books are written on this topic and I won't be able to give a full explanation for every single line in my code, but instead will attempt to present the most important ideas behind 3D visualisation.

In order to generate any 3D terrain model, you will need some grid based data with X, Y and Z values for each grid point. A very important consideration is how the Z value is stored, as DirectX uses left-handed coordinate system while OpenGL uses right-handed coordinate system (to learn about different coordinate systems, please search the Internet). I have chosen a grid size of 79x88 simply because that is how my source data is stored, but you can change this to any arbitrary grid size. Likewise, my data uses 20m resolution which means that the real distance between two adjacent points is 20 meters.

Point Mode

Once you read in all the points you will need to generate a "mesh". The mesh is an array of triangles constructed from the points you loaded in the previous step. All rendering in 3D is based on triangles and arrays of triangles.

Wireframe Mode

Even the meanest video cards on today's market have limited rendering capability in terms of how many triangles can be drawn per second. Therefore, the less work your video card needs to perform the faster your application runs. This is where optimisation algorithms come into play, such as ROAM or PLOD (the latter is built-in DirectX 9). These and other similar algorithms are aimed at reducing the level of detail and number of triangles located furthest from the view point. The other way to look at this is to say that we are reducing the level of detail where it matters least, while we are preserving the highest possible level of detail where it matters most. We won't be using these algorithms here, however you should be aware of what they are and what they are used for.

Finally, textures are used to provide a more realistic look of the scene. Textures use their own coordinate system, with top left representing 0,0 and bottom right representing 1,1. Any texture point within this range (0,0 - 1,1) is referred to as a "texel".

Textured Mode

As an exercise left to the reader, further enhancements could include the SkyBox, Lighting, Shading or even Physics engine with collision detection etc. Managed DirectX also includes support for DirectPlay and DirectSound with advanced networking and sound APIs. Using your imagination, the sky is the limit!

Using the code

I have built a sample WinForm application using the Visual Studio 2005 IDE. You will need to have Managed DirectX 9.0c SDK installed on your PC for the project to compile and run correctly (I used the August 2005 update). However you can use a much smaller DirectX 9.0c redistributable if you wish to distribute your code to users who don't have Managed DirectX SDK installed on their PC.

OK, let's dive into the code.

First of all, we will import the necessary libraries:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.DirectInput;

Then, we will declare our grid width and height, screen and keyboard devices, VertexBuffer and IndexBuffer, Texture, Vertex and Triangle structs and a few other variables used throughout the project:

private int GRID_WIDTH = 79;     // grid width
private int GRID_HEIGHT = 88;    // grid height
private Microsoft.DirectX.Direct3D.Device device = null;  // device object
private Microsoft.DirectX.DirectInput.Device keyb = null; // keyboard
private float angleZ = 0f;       // POV Z
private float angleX = 0f;       // POV X
private float[,] heightData;     // array storing our height data
private int[] indices;           // indices array
private IndexBuffer ib = null; 
private VertexBuffer vb = null;
private Texture tex = null;
//Points (Vertices)
public struct dVertex
{
  public float x;
  public float y;
  public float z;
}
//Created Triangles, vv# are the vertex pointers
public struct dTriangle
{
  public long vv0;
  public long vv1;
  public long vv2;
}
private System.ComponentModel.Container components = null;

Now we're ready to initialise our Direct3D device object:

// define parameters for our Device object
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.EnableAutoDepthStencil = true;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
// declare the Device object
device = new Microsoft.DirectX.Direct3D.Device(0, 
             Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, 
             CreateFlags.SoftwareVertexProcessing, presentParams);
device.RenderState.FillMode = FillMode.Solid;
device.RenderState.CullMode = Cull.None;
// Hook the device reset event
device.DeviceReset += new EventHandler(this.OnDeviceReset);
this.OnDeviceReset(device, null);
this.Resize += new EventHandler(this.OnResize);

As you can see we have wired up the OnDeviceReset event which fires up every time the user resizes the application window. Our points are stored in a VertexBuffer:

// create VertexBuffer to store the points
vb = new VertexBuffer(typeof(CustomVertex.PositionTextured), 
         GRID_WIDTH * GRID_HEIGHT, device, Usage.Dynamic | Usage.WriteOnly, 
         CustomVertex.PositionTextured.Format, Pool.Default);
vb.Created += new EventHandler(this.OnVertexBufferCreate);
OnVertexBufferCreate(vb, null);

Then, we need to instantiate an IndexBuffer, from which our triangular mesh is constructed. IndexBuffer stores an ordered list into the Vertex data:

ib = new IndexBuffer(typeof(int), (GRID_WIDTH - 1) * 
     (GRID_HEIGHT - 1) * 6, device, Usage.WriteOnly, Pool.Default);
ib.Created += new EventHandler(this.OnIndexBufferCreate);
OnIndexBufferCreate(ib, null);

Also pay attention to InitialiseIndices() and LoadHeightData() functions in the source code attached, where we load and "triangulate" our data. Next, we initialise the keyboard device:

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

Then, we position our camera:

private void CameraPositioning()
{
  device.Transform.Projection = 
     Matrix.PerspectiveFovLH((float)Math.PI/4,   
     this.Width/this.Height, 1f, 350f);
  device.Transform.View = 
     Matrix.LookAtLH(new Vector3(0, -70, -35), new Vector3(0, -5, 0), 
     new Vector3(0, 1, 0));
  device.RenderState.Lighting = false;
  device.RenderState.CullMode = Cull.None;
}

Almost done, only a few steps left. Now we will override the OnPaint event and provide our own event handling code:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
  device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LightBlue , 1.0f, 0);
  // set the camera position
  CameraPositioning();
  // draw the scene     
  device.BeginScene();
  device.SetTexture(0, tex);
  device.VertexFormat = CustomVertex.PositionTextured.Format;
  device.SetStreamSource(0, vb, 0);
  device.Indices = ib;
  device.Transform.World = 
         Matrix.Translation(-GRID_WIDTH/2, -GRID_HEIGHT/2, 0) *   
         Matrix.RotationZ(angleZ)*Matrix.RotationX(angleX);
  device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, GRID_WIDTH * 
                               GRID_HEIGHT, 0, indices.Length/3);
  device.EndScene(); 
  device.Present();
  this.Invalidate();
  ReadKeyboard();
}

Finally, we need to write our main procedure and we're done:

static void Main() 
{
  using (WinForm directx_form = new WinForm())
  {
    directx_form.LoadHeightData();
    directx_form.InitialiseIndices();
    directx_form.InitialiseDevice();
    directx_form.InitialiseKeyboard();
    directx_form.CameraPositioning();
    directx_form.Show();
    Application.Run(directx_form);
  }
}

Now compile and run. You should get the results as shown in the pictures at the top. Use the arrow keys on your keyboard to drive the application, and press P, W and S to switch between different rendering modes: Point, Wire frame and Solid. Cool, huh?

Points to note

One thing you'll quickly learn to appreciate is how time consuming 3D programming can be. Even the smallest detail or effect you wish to implement could take many painful days; however, the entire experience is very rewarding once you overcome the hurdles. My suggestion to everyone is to use the Internet in the first instance and search about the problem you're trying to solve. The chances are, someone has already done what you're trying to do, and better still, the problem may have been documented and solved. If you're lucky, a step-by-step tutorial or code snippets may be readily available showing you how to solve your problem.

References

  • For those people who have some spare cash in their wallets, there is an excellent book available for Managed DirectX programming in C#:
    • Managed DirectX 9 - Graphics and Game Programming, by Tom Miller.
  • Also, as a starting point there is an excellent DirectX 9 tutorial using C# available here.
  • Another great site with lots of practical examples in DX9 and C# is available here.

History

  • 19th September 2005: First release.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Igor Stjepanovic
Founder GIS People
Australia Australia
Member
I have filled variety of roles ranging from Junior Software Engineer to GIS Team Leader. My background is in real-time spatial solutions, including mobile data capture and advanced road network data modelling.
 
In my projects I have utilised and integrated technologies such as GPS, Oracle Spatial, FME, MapInfo and ESRI suite of tools.
 
I'm proficient in all aspects of the software development lifecycle and I'm holding a degree in Computer Science from Queensland University of Technology.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCompilation with Visual Studio 2010memberGagnon Claude29 Jun '11 - 16:36 
Hi,
 
I want to compile it with Visual Studio 2010. It seems to work but when I run the application, it's not working.
 

Call stack:
3d_terrain_visualisation.exe!Brisbane.WinForm.Main() Line 351 + 0x1c bytes
 
using (WinForm directx_form = new WinForm())
 
Any hints?
 

Thanks,
 
Claude
AnswerRe: Compilation with Visual Studio 2010memberschubert0125 Aug '11 - 17:49 
I see the same problem when using VS2010.
GeneralRe: Compilation with Visual Studio 2010 [modified]memberIgor Stjepanovic27 Aug '11 - 22:21 
I'm sorry, but I wrote this article exactly 6 years ago, and I never tried to compile the code under VS2010. The issue is perhaps Managed DirectX SDK more so than the Visual Studio IDE.
 

 
-- Modified Sunday, August 28, 2011 4:28 AM
Generalsize limitation on overlay bitmapmemberslavo.salma13 May '09 - 14:11 
Hi Igor,
 
Thank for great example how to greate terrain mesh with overlay. Do you know what is the pixel rows/cols limit for DirectX? I'm just wondering if I use high res aerial image.
 
cheers,
Slavo
GeneralRe: size limitation on overlay bitmapmemberIgor Stjepanovic13 Aug '09 - 15:32 
Hi Slavo,
 
sorry, but I'm not sure if there's a physical limit imposed on the size of bitmap. But even if there isn't, the problem you'll have with high res stuff is the performance. So a much better way to handle this would be to have bitmaps (textures really) with different levels of detail. So, as you're zooming out, the app is rendering lower res bitmap, that covers greater distance, while as you're zooming in, the app will use the higher res textures.
 
You should also try to reduce the number of vertices as you're zooming out.
 
Hope this helps,
Igor
QuestionFullScreen? Is the Windows.Form neccessary?memberMember 427848522 Oct '08 - 21:00 
Is there any pull back using Windows.Form?
How to make this example into full screen? Form.Windowed = false?
 
This is a really nice sample, thank you so much!
GeneralManaged DirectXmembernewspicy16 Sep '08 - 2:30 
I belieave Managed DirectX is considerd finish to use anymore.
What options could it have then?
Is it painful to use Direct3D 10 invoked calls in C# ?
Someone who has try?
Maby its better to use the old classic C++ Win32 combined with Direct3D 10.
But not sure.
QuestionBlue screenmemberTaher Hassan25 Nov '07 - 12:37 
Thanks for sharing your code. I was trying to go through it however, i got this empty blue screen. I found that one guy had the same problem and you suggested replacing one line of code to get it working. I tried your suggestion, but it gave me exception.
Do u have and tips to help out.
many thanks
 
Taher Hassan
University of Calgary

General3d games in directxmemberRick8124 Sep '07 - 7:58 
Has anyone written a simple 3d engine to be used in games? I'd like to get some basics to start with.
 
If you want to upload your own programs and games, visit my site http://www.mysmallprograms.com/
Generalgrid sizememberjtby230 Aug '07 - 12:21 
nice example! How big can the grid and texture be? are there limits?

GeneralRe: grid sizememberIgor Stjepanovic13 Aug '09 - 15:37 
Actually I don't know if there's a physical limit, but you have to think about performance if you're intending to create a single mesh of the universe Frown | :(
 
You'll generally need to "tile" the world, and only render those tiles that are "visible". There are plenty of books written on the topic, so I can't answer your question in a short email, sorry :(
GeneralZ-Buffermembersithira7730 Jul '07 - 23:27 
Hi!
Could you please explain me, how to write z-values in to the Z-buffer with C#? If you can please give some example.
Thank you in advance.
 

 
Sith
GeneralRe: Z-BuffermemberIgor Stjepanovic15 Aug '07 - 15:00 
Hi Sith,
 
there are many examples on the web - just a Google for it... BTW, there are good books that you may wish to purchase to learn the basics - I learned most of the 3d programming from a single book...
 
Sorry, can't give you any examples, I'm way to busy at work.
 
Regards,
Igor
Generalfloat.Parsemembergajatko1 Jul '07 - 2:38 
Do not use float.Parse(string) in method LoadHeightData()
 
Use
Single.Parse(string input)
when you are parsing user's input.
 
Use
Single.Parse(string data, System.Globalization.NumberFormatInfo.InvariantInfo)
when parsing internal data.
 
In LoadHeightData() you parse internal data (with dots), so write your own parser or use invaraiant culture.
 
Why? Because various cultures use various float separators. E.g in polish: ',' and in english: '.'. Maybe there are also other differences in other languages, so it is most safe to always use an invariant parser.
 
Anyway, great work.
 
Greetings - gajatko.
GeneralRe: float.Parsemembergajatko2 Jul '07 - 0:02 
Oh now I noticed that ivandasch already sent similar post.
 
Anyway, here is another solution, which enables using current culture as default and invariant if necessary.
 
- gajatko
GeneralData typemembermuzzaukuk24 Nov '06 - 11:06 
Hi can you explain the grid type you use to store the data?
GeneralVirusmemberMurray Roke11 Jul '06 - 1:11 
Hi Igor,
AVG found a virus in your project zip file.
 
Cheers.
Murray.
GeneralRe: VirusmemberIgor Stjepanovic11 Jul '06 - 1:13 
My apologies,
 
sorry, my anti-virus didn't find anything........
 
Igor
GeneralPlease take a minute to votememberIgor Stjepanovic9 Jul '06 - 22:44 
Hi all,
 
I appreciate your kind comments but I noticed that hardly anyone votes for this article, which is unfortunate as my article is therefore not gaining any popularity. Please take time to submit your vote, please.
 
Regards,
Igor Big Grin | :-D
GeneralRe: Please take a minute to votemembergiloutho10 Jul '06 - 1:10 
You're right Igor... I voted...
 
Regards
 
Gil
 

GeneralRe: Please take a minute to votememberDarren Ashenden19 Feb '07 - 14:31 
Hey Igor, good to see you still going strong.
The article is great, clear and simple good job.
Dazza the Dangerous Big Grin | :-D
GeneralProblems in localized Windows [modified]memberivandasch20 Jun '06 - 8:59 
When somebody try to run this app in some localized(i.e. russian) versions of MS Windows some problem can occur - debugger reports, that in method LoadHeightData() app try to convert string, that have read two lines before from file. There is stupid thing, but some guys from Microsoft think(they know better russian langugage,than russians do)that russians use comma as decimal point !!. If you want to run this app in every version of Windows without problem , you must add some lines of code.
In header add this stuff:
using System.Threading;
using System.Globalization;

In method Main() add this:
static void Main()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-us"); ....
}

Thanks for good app. Big Grin | :-D
 
-- modified at 15:03 Tuesday 20th June, 2006
GeneralRe: Problems in localized Windowsmembergiloutho9 Jul '06 - 0:59 
Thanks a lot Ivan, I've the problem with french configuration.
 
Many thanks to Igor for this great article
 


GeneralZoom In/Out ..membersahiljain2223 May '06 - 20:06 
Hey, Good Job man ~ Can you help me implement Zoom In/Out function in your program? I dont need the code, just a overall idea how to do it and where to start. I'm pretty new to directx as you can see.
Thanks.
 
Here are a fixes I found: If you get a blue screen, you have to change the 3D Rendering mode to Reference from Hardware.
GeneralRe: Zoom In/Out ..memberIgor Stjepanovic28 May '06 - 18:53 
Hi there,
 
my appologies for taking this long to respond. You have 2 options:
 
1. move the camera to/from the mesh (terrain)
2. move the terrain relative to some "origin" and leave the camera static.
 
I am sorry but I do not have the time (work is keeping me very busy) to give some code - but just look for directx tutorials on google and you will find plenty of examples.
 
Hope this helps...
 
Igor
GeneralRe: Zoom In/Out ..memberIgor Stjepanovic4 Jun '06 - 20:52 
A link full of Managed DirectX tutorials for those interested:
 
http://www.riemers.net/[^]
 
Hope it helps - Igor
GeneralRe: Zoom In/Out ..memberAndrew Phillips8 Aug '07 - 19:55 
Surely zoom is just a matter of changing the aperture without moving anything.

 
Andrew Phillips
http://hexedit.com
andrew @ hexedit.com

QuestionHow to add a 3D point object to viewer?memberPhil J B14 May '06 - 17:31 
Hi...
 
Yer, really nice articleBig Grin | :-D ...I'm another GIS person playing about with C# and very happy to see your DirectX example... thanks for sharing your code and time.
 
It all works cool for me, although I'm still trying to understand it! WTF | :WTF:
 
So it reads in the DSM file using some grid coordinate system values (eg x and y are big numbers in metres in your TXT file).. then applies the texture to it (JPG).
 
Could you also add a separate point object (sphere) into the viewer at a given location?
 
For example if I wanted to show in 3D the location of someone at a known location in the same coord system as the original DEM.. how would you go about plotting this point as a separate object on the DSM?
 
Thanks,
Phil
AnswerRe: How to add a 3D point object to viewer?memberIgor Stjepanovic16 May '06 - 13:09 
Hi Phil,
 
You got it right. The app reads in an array of "spot heights", creates a "mesh" and drapes a texture over the mesh. I haven't posted and implemented too many "features" since this article is supposed to introduce you to a great world of 3d programming, and not confuse you.
 
It is most certainly possible to place custom objects into the scene, in fact, the terrain i built is a pretty complex object compared to a simple sphere (which is built into directx). Take a look at the book I have mentioned; if you're really serious about 3d programming pick it up it's pretty good.
 
The trick with my app is that all points in the scene are "geo referenced" and you can easily place custom objects at the exact geographic location...
 
Sorry, can't write more code at the moment, the work is keeping me (VERY) busy Cry | :((
GeneralRe: How to add a 3D point object to viewer?memberPhil J B16 May '06 - 14:19 
Ok thanks for the reply Igor...
 
Will try and find that book, if get anything to work I'll post the code...
 
Ta,
Phil
AnswerRe: Sorry, but i need your helpmemberIgor Stjepanovic8 May '06 - 1:11 
There's nothing secret about it - you can work it out yourself by simply replacing the GRID_WIDTH + GRID_HEIGHT variables with their corresponding values. This function will generate the array that stores indices from which the triangular mesh is generated...Hope it helps,
 
Igor
QuestionRe: Sorry, but i need your helpmembercloogey5 Oct '06 - 11:58 
i have been trying to decipher this as well,WTF | :WTF:
could explain this out a little more please:
 
1 -i see you are builing vertices but I am not following why you are building 6 vertices and also why in that order, how is each vertice computed - logically speaking
2 -how and where are you building the texture is it the same as the mesh and where is the mesh being overlayed on the triangles, or does directX give the texture automatically when you hand it the vertices?

GeneralGot a blue windowmemberGrayGryphon22 Feb '06 - 18:49 
First for all Igor, on behalf of all newbies, I would like to thank you for your very well written and easy-to-understand tutorial. I tried to run your sample app but encountered some problems which I have solved (such as missing m15.txt, wrong version of Visual Studio .NET, etc.) I got the app to run but all I get is the WinForm window colored light blue and nothing else. I know that is from the line of code:
 
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LightBlue , 1.0f, 0);
 
But how do I make the terrain model appear? I had copied all the JPGs to the correct directory with m15.txt.
 
Best Rdgs
 
Cassidy
GeneralRe: Got a blue windowmemberGrayGryphon23 Feb '06 - 15:29 
This is a self reply. Found out what's wrong. My old test PC has an Intel Extreme Graphics 82845G display adaptor. I think it is not direct x 9 compatible. Switched the line:
 
device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
 
to:
 
device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Reference, this, CreateFlags.SoftwareVertexProcessing, presentParams);

and managed to get it working. Although understandably it very very slow.
 
Thanks for your article Igor.
 
Best Regards
GeneralRe: Got a blue windowmemberIgor Stjepanovic24 Feb '06 - 15:07 
No probs Cassidy,
 
the article was written using the IDE and .NET versions as explained, I never guaranteed that the code will work in all possible permutations of the environments without modification. As you may know, the actual Managed DirectX API unfortunatelly changes from one version to another and whilst the changes are usually very small, the newbies are finding it hard to get the sample code running.
 
My feeling is that the m15.txt file is not found, as that file contains your coordinates from which the terrain is constructed. Try putting the traces in the program to check if the file is present, ie. open the file and output the first line to a debug window. This debugging exercise will actually help you learn about how the app hangs together.
 
Cheers,
Igor
 

QuestionCamera Movement?memberbthalken6 Jan '06 - 9:08 
How would you add camera movement? I see how you can spin and tilt, but how would you be able to use keyboard input or the mouse to navigate through the environment that you generate? Any ideas?
 
Thanks.
Brian
AnswerRe: Camera Movement?memberIgor Stjepanovic26 Jan '06 - 11:37 
Hello Brian,
 
sorry for this delay. Actually, it is possible and easy to move the camera (don't have any code at hand, search Google and you'll find example), but most people recommend that you do not move the camera but your world instead. For example, so simulate the camera movement forward, you move your world towards the camera. Does this make any sense? This is done basically to simplify your code. Sorry, can't help more right now. Cheers,
 
Igor
QuestionUseing procedural texturing with GIS-datamemberHans Ekstrom7 Dec '05 - 4:59 
Hi Igor! Thank you for sharing your code! I´m a student from Sweden who are about to begin an individual project in a course called "Procedural methods for Images". I was thinking of building a real time terrain renderer with C# and D3D, generating a terrain from a procedural made hight map and then put procedural textures on it with HLSL (High Level Shading Language). Now to my questions. Instead of generating the terrain from a bitmap, it would be great to do it like you do in your example. Is it possible to get free GIS-data somewhere? Do you have any experience of using procedural texturing and modelling with GIS-data? I´m totaly lost on GIS, but something tells me it could be a really nice combination!
AnswerRe: Useing procedural texturing with GIS-datamemberIgor Stjepanovic8 Dec '05 - 10:54 
Hi Hans,
 
not sure what you mean by procedural height maps and procedural textures. But it is certainly possible to read the height data from a height map - there's plenty of examples on the net on how to do this.
 
There's plenty of free GIS data, but some of it is rather useless. Look for DEM's (Digital Elevation Models) or visit the site mentioned by one of the posters on this forum. Or best of all, talk to your Local Government Authority (city council), they will most definatelly have plenty of GIS data to give away - I know ours does! You just need to mention that you're a student and explain what you're after. Let me know how you go Smile | :)
 
Igor
GeneralNon-gridded datamemberMorten on GIS6 Dec '05 - 22:11 
Can I use height-data which isn't in a regular grid? I wan't to save some vertices/triangles by thinning the points in the flat areas.
 
Furthermore... if I have vector data, for instance roads, how can I drape a line with a given thickness on to the terrain? If this is possible, it would be a way cool way of creating a 3D thematic map.
GeneralRe: Non-gridded datamemberIgor Stjepanovic6 Dec '05 - 22:46 
I guess you asked 2 questions.
 
1. Yes, it is posible BUT your will make a life a lot more difficult for yourself. My advice: use gridded data only (http://www.cse.unsw.edu.au/~lambert/java/3d/delaunay.html[^]). Oh, byt the way I used delaunay trinagulation to start of with this project but changed later to normal grid for good. It is always easier to pre-process your data into regular grid data than deal with non-gridded data in your code...Hope this makes sense...
 
2. Typically you'd be draping a raster image (jpg, gif, bmp, ecw) over a terrain mesh. I am not aware of the way to drape a vector map over the terrain mesh. But you could rasterise your road network and achieve the same result. If you use ECW file format (which can store images as multiple resolutions) you can achieve a similar effect with a VERY small loss in quality.
 
BTW, the work you're doing with SharpMap is very cool. Ilike it very much, but would like to see Oracle Spatial support thrown in at some point (now that would be mega cool!).
 
Hope it helps,
Igor
 
-- modified at 4:51 Wednesday 7th December, 2005
GeneralRe: Non-gridded datamemberMorten on GIS6 Dec '05 - 23:15 
Regarding 1:
Yeah well I guess I only have to go through the preproccesing only once. So I don't think that is a big problem.
 
2)
GoogleEarth does it (so I guess DirectX/OpenGL supports it), and it would give great flexibility if you for instance could load any shapefile, change the color etc. without rasterizing the data. And you would be able to transfer less data using a vector format than a raster format.
 
Thank you for the kind words regarding SharpMap. Oracle support shouldn't be too big a problem. You could just implement the IProvider interface (and I guess you could take the PostGIS provider and copy most from there). The PostGIS provider was very easy to make, and I would figure that it would be the same case with Oracle.
GeneralPower of twomemberMorten on GIS6 Dec '05 - 21:40 
Just wanted to add that you should always make the size of images to the power of two (that is 1,2,4,8,16,32,64,128,512,1024...). You will get better performance and faster load-time by resizing the images to 512x512.
GeneralRe: Power of twomemberIgor Stjepanovic6 Dec '05 - 22:37 
Yes, you're right. The only trouble is my data was available in the sizes I have used - and I'm lazy enough to worry about those minor details such as grid sizes Smile | :)
 
Just kidding, your point is spot on.
GeneralError in OnVertexBufferCreate...memberbukagija24 Nov '05 - 4:56 
I'm using .NET 2003 and Managed DirectX 9 SDK (august 2005).
 
I have the following problem:
 
in
 
private void OnVertexBufferCreate(object sender, EventArgs e)
{
string line;
string[] point;
float u, v;

// create texture (you can replace 2001.jpg with other images attached to this project)
tex = new Texture(device, new Bitmap("2001.jpg"), Usage.Dynamic, Pool.Default);
 
....
 
I get an exception:
 
An unhandled exception of type 'Microsoft.DirectX.Direct3D.InvalidCallException' occurred in microsoft.directx.direct3d.dll
 
I am certain that the Bitmap is present and OK.
Could it be something wrong with the "device" parameter passed in this call
(note: "device" != null)
 
Thanx.

GeneralRe: Error in OnVertexBufferCreate...memberbukagija24 Nov '05 - 5:14 
Ok, I'm self-replying but might be usefull to others Smile | :)
 
public void InitialiseDevice()
{
...
// declare the Device object
device = new Microsoft.DirectX.Direct3D.Device(0, Microsoft.DirectX.Direct3D.DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
...
 
Apparently when I use
Microsoft.DirectX.Direct3D.DeviceType.Reference
or
Microsoft.DirectX.Direct3D.DeviceType.NullReference
 
instead of the above:
Microsoft.DirectX.Direct3D.DeviceType.Hardware
 
it works but of course very, very, veeeery slooow
(who needs hdw acceleration, right? Smile | :) )
 

 


GeneralRe: Error in OnVertexBufferCreate...memberIgor Stjepanovic25 Nov '05 - 0:27 
Bukagija,
 
Can I suggest to check your hardware - make sure your video card is supported by Managed DirectX 9.0c. Google your problem and your bound to find other people with the same issue - however you're the first reader of my article who has reported this problem...
 
Igor
GeneralGood think, I need Help in Managed DirectXmemberwalid10018 Nov '05 - 14:54 
Hello, you article is a very good demonstration of the capablity of managed DirectX in relizing very powerfull application with very small sheet of code.
 
Mr I have a probleme, I'm Writing a small application with c# and Managed DirectX 9.0. and I need to resize the window without keeping Aspect ratio. I want to get the same dimontion of the objects when I resize the window.
 


GeneralRe: Good think, I need Help in Managed DirectXmemberIgor Stjepanovic8 Nov '05 - 21:19 
Walid,
 
I understand your question but don't know the answer - sorry. Hopefully someone else reading this message can give us a tip?
 
Igor
GeneralRe: Good think, I need Help in Managed DirectXmemberwalid10019 Nov '05 - 3:13 
thanks for your responding, if you get any idea please contacte Me

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 18 Sep 2005
Article Copyright 2005 by Igor Stjepanovic
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid