我对 DirectX 库有点陌生,我想知道是否有人可以帮助我解决相机问题。在我的主表单中,我加载了一组表示 3D 对象的多边形数据,然后将该多边形数据传递给另一个表单,并希望将多边形绘制为三角形列表。不幸的是,我似乎无法让相机达到 1)具有正确的视锥或 2)让相机正确聚焦和调整图像大小。多边形数据正在作为世界坐标数据加载。
下面是初始化二级窗体、directx、camera等的代码。
#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