# [MDX] Almost there....

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

## 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();
}

public void InitGFX()
{
pp.Windowed = true;
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();
}

{

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;
}
}

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;
}
}
}

{
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 = 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 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 on other sites
I tried passing this, this.Handle to the Device constructor, but to no avail. I will look into handling the DeviceLost event. Thanks for the info.

-AJ

##### 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