[.net] Nothing visible in Managed DirectX

Started by
11 comments, last by paulecoyote 18 years, 10 months ago
Hi there, After doing a bunch of Managed DirectX tutorials, I wanted to create something nice with it, so I've written a very basic random terrain generator. The generated terrain looks quite good when imported in Blender: Now the problem is that my renderer doesn't work. The polys that are generated are good, and the Render method is being called, because the window is cleared in the clear color. Here is the renderer code:

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

namespace TerrainGenerator
{
	class Renderer
	{
		private Form form;
		private Device device;
		private VertexBuffer buffer;

		private Matrix worldMatrix = new Matrix();
		private Matrix projectionMatrix = new Matrix();
		private Matrix viewMatrix = new Matrix();

		private Vector3 eyeVector;
		private Vector3 lookVector;
		private Vector3 upVector;

		private int count;

		private void dumpVertex(CustomVertex.PositionColored vertex)
		{
			Console.Write(string.Format("{0} {1} {2}", vertex.X, vertex.Y, vertex.Z).Replace(',', '.'));
		}

		private void dumpTriangle(CustomVertex.PositionColored[] triangle)
		{
			foreach (CustomVertex.PositionColored vertex in triangle)
			{
				dumpVertex(vertex);
				Console.Write(' ');
			}
			Console.WriteLine();
		}

		public Renderer()
		{
			form = new Form();
			form.Text = "Sijmen\'s terrain generator";
			form.ClientSize = new Size(800, 600);
			form.BackColor = Color.Gray;
			form.MinimizeBox = false;
		}

		public void Initialize()
		{
			form.Show();

			// setup directix

			PresentParameters pp = new PresentParameters();
			pp.Windowed = true;
			pp.SwapEffect = SwapEffect.Discard;

			device = new Device(0, DeviceType.Hardware, form, CreateFlags.SoftwareVertexProcessing, pp);
			device.RenderState.Lighting = false;

			// setup matrices

			eyeVector = new Vector3(0.0f, 0.0f, -50.0f);
			lookVector = new Vector3(0.0f, 0.0f, 0.0f);
			upVector = new Vector3(0.0f, 0.0f, 1.0f);

			viewMatrix = Matrix.LookAtLH(eyeVector, lookVector, upVector);
			projectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 2), 1.0f, 1.0f, 1000.0f);

			device.Transform.View = viewMatrix;
			device.Transform.Projection = projectionMatrix;
			device.Transform.World = worldMatrix;
		}

		public void LoadMap(Vector3[,] data, int width, int height)
		{
			List<CustomVertex.PositionColored> triangles = new List<CustomVertex.PositionColored>();

			Console.WriteLine("Triangles");

			for (int x = 0; x < width - 1; x++)
			{
				for (int y = 0; y < height - 1; y++)
				{
					Vector3 tl = data[x, y];
					Vector3 tr = data[x + 1, y];
					Vector3 bl = data[x, y + 1];
					Vector3 br = data[x + 1, y + 1];

					CustomVertex.PositionColored[] triangle1 = new CustomVertex.PositionColored[]
						{
							new CustomVertex.PositionColored(tl, 0xff0000),
							new CustomVertex.PositionColored(bl, 0xff0000),
							new CustomVertex.PositionColored(tr, 0xff0000)
						};
					CustomVertex.PositionColored[] triangle2 = new CustomVertex.PositionColored[]
						{
							new CustomVertex.PositionColored(bl, 0x0000ff),
							new CustomVertex.PositionColored(tr, 0x0000ff),
							new CustomVertex.PositionColored(br, 0x0000ff)
						};

					//dumpTriangle(triangle1);
					//dumpTriangle(triangle2);

					triangles.AddRange(triangle1);
					triangles.AddRange(triangle2);
				}
			}

			//Console.WriteLine();

			count = triangles.Count;
			buffer = new VertexBuffer(typeof(CustomVertex.PositionColored), count, device, 0, CustomVertex.PositionColored.Format,
				Pool.Managed);

			GraphicsStream stream = buffer.Lock(0, 0, 0);
			stream.Write(triangles.ToArray());
			buffer.Unlock();
		}

		public void Render()
		{
			device.Clear(ClearFlags.Target, Color.DarkGreen, 1.0f, 0);
			device.BeginScene();

			device.SetStreamSource(0, buffer, 0);
			device.VertexFormat = CustomVertex.PositionColored.Format;
			device.DrawPrimitives(PrimitiveType.TriangleList, 0, count / 3);

			device.EndScene();
			device.Present();

			Application.DoEvents();
		}

		public bool ShouldRender
		{
			get { return form.Created; }
		}
	}
}


There's also a pastebinned version available here. What I've already tried, with the help of some kind people at #gamedev: - Inverted the drawing order of half the polygons, so that there would be something visible when seen from both angles; - Moved the camera everywhere; - Change the up angle. The up angle is Z, because the terrain is on the XY plane. When the program is run, I can see no polygons. Any idea why this is so? Thanks in advance!
Advertisement
could it be because there is no light source?
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
Quote:Original post by paulecoyote
could it be because there is no light source?


I have already disabled lightning. But even then, i should at least see the black polygons ontop of the yellow/green/whatever background...
I dunno, it's hard to guess because the rest of the app isn't there.

Well you've already tried moving the camera, have you tried scaling the terrain,
perhaps even normalise it (so the positions all falls between 0 - 1)?

I know when I first started I had this happen to me and it was something to do with the lighting (and nothing not even black was on the screen - because the materials were not properly doing the ambient light and other stuff), but like you said you've turned it off...
Anything posted is personal opinion which does not in anyway reflect or represent my employer. Any code and opinion is expressed “as is” and used at your own risk – it does not constitute a legal relationship of any kind.
I looked quickly through your code and I did not see you set the world matrix to a valid value. 'new Matrix()' creates an empty matrix which is not a valid transform. Try initalizing it to Matrix.Identity instead.
/frontedit
I forgot to mention that I swapped the triangle list for a point list, disabled backface culling, and set fill mode to points, just to be sure. The following is a followup to that. So, culling disabled, fillmode = points, and now a point list.


Woo, I can finally see something. I've set the world matrix to identity, and now I can see one blue dot in the center. I've tried moving the camera around a bit, but it's still only the blue dot.

As soon as I start using triangle lists again, all is empty once more. So, finally getting somewhere - any more ideas?
No idea what your data looks like, but try just getting a really simple triangle to render. First try DrawUserPrimitives with an array of one of the Transformed vertex types specifiec in screen space (position values in the hundreds should be visible) to see if you are actually drawing. Next try an untransformed triangle with position values in the teens to see if your transforms are good. If your data still does not work it may be the way you are building the buffer.

Some more things:
The up vector of your camera should probably be (0,1,0) y = up and not (0,0,1) z = up. -50 in z for the position is really far away (a sphere with a radius of 1 will mostly fill the screen with a fov of pi/4 and a z-position of -3). 1000 is a very far far plane and may cause zbuffer issuses.
Thanks for the info, I will try all this tomorrow!
Okay, I've got it to work.

First I've drawn an untransformed triangle, which worked after setting the world matrix to Matrix.Identity. Next, I've set the up vertex to Y, and drawn a positioned triangle, which was going fine, too.

Finally, I've adjusted the generator to generate on the XZ plane, with Y as evelation. That worked, and after setting the eye, all was fine. I'll post some screenshots and an exe later!

Thanks for the kind help!
Quote:Original post by Sijmen
Okay, I've got it to work.

Sweet.

This topic is closed to new replies.

Advertisement