I am a bit new to the DirectX library and I am wondering if anyone can help me with a camera issue. In my main form I load a set of polygon data representing a 3D object and then pass that polygon data to another form and want to draw the polygon as a triangle list. Unfortunately I cannot seem to get the camera to either 1) Have the proper viewing frustum or 2) Get the camera to properly focus and size the image. The polygon data is being loaded as world coordinate data.
Below is the code that initializes the secondary form, directx, camera, etc.
#region Public Members
/// <summary>
/// Default Constructor.
/// </summary>
public STLViewer()
{
// Set the form size, form text, icon
this.ClientSize = new Size(500, 500);
this.Text = "Object Name: " + stlFile.SolidName + ", Polygon Count: " + stlFile.GetPolygons().Count;
this.Icon = RetrieveFormIcon();
// Change our drawing style so there is no drawing happening outside our main form
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
// Get our vertex data in a prepared format
verts = PrepareObjectForRender();
}
/// <summary>
/// This function is responsible for retrieving the specified
/// icon from the assembly.
/// </summary>
/// <returns>Form icon</returns>
private Icon RetrieveFormIcon()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Stream str = assembly.GetManifestResourceStream(icon);
return new Icon(str);
}
#endregion
#region Main Line
public static void Main()
{
// Create our form object
STLViewer stlViewer = new STLViewer();
// Initialize D3D
if (stlViewer.InitializeDirect3D() == false)
{
MessageBox.Show("Could not initialize Direct3D.", "Error");
return;
}
// Display our form
stlViewer.Show();
// Main message loop
while (stlViewer.Created)
{
// Keep rendering the image until the form is terminated
//stlViewer.Render();
// Handle aall events here: keyboard, mouse, etc.
Application.DoEvents();
}
}
#endregion
#region Rendering
protected override void OnPaint(PaintEventArgs e)
{
if (directXDevice.RenderState.FillMode == FillMode.Solid)
{
directXDevice.RenderState.FillMode = FillMode.WireFrame;
}
// Clear the window to black
directXDevice.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
// Setup the camera for viewing
SetupCamera();
// Begin the rendering process
directXDevice.BeginScene();
// Set the vertext format
directXDevice.VertexFormat = CustomVertex.PositionColored.Format;
// Draw our vertices
directXDevice.DrawUserPrimitives(PrimitiveType.TriangleList, stlFile.GetPolygons().Count, verts);
// End rendering and present the drawing to the screen
directXDevice.EndScene();
directXDevice.Present();
// Force our form to refresh its viewing area
this.Invalidate();
}
/// <summary>
/// This function is responsible for rendering the image
/// to the screen.
/// </summary>
private void Render()
{
// IF we cannot connect to a device then return
if (directXDevice == null)
{
return;
}
// Get our vertex data in a prepared format
CustomVertex.PositionColored[] verts = PrepareObjectForRender();
// Clear the window to black
directXDevice.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
// Setup the camera for viewing
SetupCamera();
// Begin the rendering process
directXDevice.BeginScene();
// Set the vertext format
directXDevice.VertexFormat = CustomVertex.PositionColored.Format;
// Draw our vertices
directXDevice.DrawUserPrimitives(PrimitiveType.TriangleList, stlFile.GetPolygons().Count, verts);
// End rendering and present the drawing to the screen
directXDevice.EndScene();
directXDevice.Present();
}
/// <summary>
/// This function is responsible for creating the necessary
/// DirectX objects, setting the vertices and normals, colors
/// and/or materials for the object so we can draw it in the
/// form.
/// </summary>
private CustomVertex.PositionColored[] PrepareObjectForRender()
{
// List to hold our colored vertices
List<CustomVertex.PositionColored> vertices = new List<CustomVertex.PositionColored>();
// List to hold our polygons, contained within the STL file
List<Polygon.Polygon> polygons = stlFile.GetPolygons();
// Create a custom vertex that will be used to hold our vertices
CustomVertex.PositionColored custVert = new CustomVertex.PositionColored();
// Iterate through our polygons and pulled a vertex list
for (int i = 0; i < polygons.Count; i++)
{
// Set the position and color of our 1st vertex in our polygon, add it to our list
custVert.Position = new Vector3((float)polygons[i].GetDoublePoints1()[0],
(float)polygons[i].GetDoublePoints1()[1], (float)polygons[i].GetDoublePoints1()[2]);
custVert.Color = Color.YellowGreen.ToArgb();
vertices.Add(custVert);
// Set the position and color of our 2nd vertex in our polygon, add it to our list
custVert.Position = new Vector3((float)polygons[i].GetDoublePoints2()[0],
(float)polygons[i].GetDoublePoints2()[1], (float)polygons[i].GetDoublePoints2()[2]);
custVert.Color = Color.YellowGreen.ToArgb();
vertices.Add(custVert);
// Set the position and color of our 3rd vertex in our polygon, add it to our list
custVert.Position = new Vector3((float)polygons[i].GetDoublePoints3()[0],
(float)polygons[i].GetDoublePoints3()[1], (float)polygons[i].GetDoublePoints3()[2]);
custVert.Color = Color.YellowGreen.ToArgb();
vertices.Add(custVert);
}
// Cast our list to an array of vertices
CustomVertex.PositionColored[] verts = vertices.ToArray();
return verts;
}
#endregion
#region Initialization & Configuration
private bool InitializeDirect3D()
{
bool retVal = false;
try
{
// Create a new PresentParameters object so our device knows how to display
PresentParameters pps = new PresentParameters();
// Display in a windowed mode
pps.Windowed = true;
// After the current screen is draw, discard it from memory
pps.SwapEffect = SwapEffect.Discard;
// Create the new D3D Device and set our PresentParameters within
directXDevice = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, pps);
// Use wireframe as our drawing mode
directXDevice.RenderState.FillMode = FillMode.WireFrame;
retVal = true;
}
catch (DirectXException e)
{
// Display our error message
MessageBox.Show(e.ToString(), "Error");
retVal = false;
}
return retVal;
}
private void SetupCamera()
{
directXDevice.Transform.Projection = Matrix.PerspectiveFovLH(1.85f,
(float)(this.Width / this.Height), 1.0f, 1.00f);
directXDevice.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 0.0f, 5.0f),
new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
directXDevice.RenderState.Lighting = false;
}
#endregion