Recently, due to the project of displaying a 3D model, I researched how to load and display the 3D model in Winform. We provided the DirectX SDK for rendering graphics on the Windows platform, and referred to several articles to create a demo record for future reference. This SDK involves some basic knowledge of computer graphics and requires some mastery. It is recommended to refer to the OpenGL beginner's manual.
Create ProjectLet's get back to the main topic. First, create a Winform project using Visual Studio 2019, and then add references to the three DirectX DLL libraries at the path: C: Windows Microsoft NET DirectX for Managed Code 1.0.2902.0, mainly consisting of the first three DLLs, with the latter available but not needed.
.
Add timer and panel controls through the toolbox, where the panel is used to display the three digit model (or it can be omitted and displayed directly in the form), and the timer is used for real-time rendering.
.
Code Implementation
/ *--------member variable declaration-----------* /
//equipment
private Device device;
//display parameters
private PresentParameters pres;
//save 3 D file
private Mesh mesh;
//rendering materials
private Material[] materials;
private Texture[] textures;
/ *--------method implementation-----------* /
public bool InitializeGraphics()
{
pres = new PresentParameters();
pres.Windowed = true;
pres.SwapEffect = SwapEffect.Discard;
pres.EnableAutoDepthStencil = true;
pres.AutoDepthStencilFormat = DepthFormat.D16;
device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing,
pres);
device.RenderState.CullMode = Cull.None;
CreateMesh(@"airplane 2.x");
//CreateMesh(@"lobby_skybox.x");
return true;
}
public void CreateMesh(string path)
{
ExtendedMaterial[] exMaterials;
mesh = Mesh.FromFile(path, MeshFlags.SystemMemory, device, out exMaterials);
if (textures != null)
{
DisposeTextures();
}
textures = new Texture[exMaterials.Length];
materials = new Material[exMaterials.Length];
for (int i = 0; i< exMaterials.Length; ++i)
{
if (exMaterials[i].TextureFilename != null)
{
string texturePath = Path.Combine(Path.GetDirectoryName(path), exMaterials[i].TextureFilename);
textures[i] = TextureLoader.FromFile(device, texturePath);
}
materials[i] = exMaterials[i].Material3D;
materials[i].Ambient = materials[i].Diffuse;
}
}
public void DisposeTextures()
{
if (textures == null)
{
return;
}
foreach (Texture t in textures)
{
if (t != null)
{
t.Dispose();
}
}
}
public void SetupMatrices()
{
float yaw = Environment.TickCount / 500.0F;
float pitch = Environment.TickCount / 500.0F;
device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, 0);
device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -6), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 2.0F, 1.0F, 1.0F, 10.0F);
}
public void SetupLights()
{
device.RenderState.Lighting = true;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Specular = Color.White;
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Direction = new Vector3(-1, -1, 3);
device.Lights[0].Enabled = true;
device.RenderState.Ambient = Color.FromArgb(0x00, 0x00, 0x00);
}
public void RenderMesh()
{
for (int i = 0; i< materials.Length; ++i)
{
if (textures[i] != null)
{
device.SetTexture(0, textures[i]);
}
device.Material = materials[i];
mesh.DrawSubset(i);
}
}
public void Render()
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0F, 0);
device.BeginScene();
SetupMatrices();
SetupLights();
RenderMesh();
device.EndScene();
device.Present();
}
public void DisposeGraphics()
{
DisposeTextures();
device.Dispose();
}
Rendering Implementation
In Form1_ Call the initialization function in the Load event, and then click the timer1 of the timer_ Call the Render function in the Tick event to render in real time.
private void Form1_Load(object sender, EventArgs e)
{
InitializeGraphics();
}
private void timer1_Tick(object sender, EventArgs e)
{
Render();
}
Compile the program, set 32-bit mode before compilation, and create a new 32-bit compilation mode yourself.
.
Prepare materials
Need to install Microsoft's DirectX SDK, link: https://www.microsoft.com/zh-cn/download/details.aspx?id= ; six thousand eight hundred and twelve.
Copy three resource files from C: Program Files (x86) Microsoft DirectX SDK (June 2010) Samples Media Airplane to the local exe file directory RobotSimulator DirectX3D bin x86 Debug in this path.
.
Run program
.
PS:
If the "Managed Debugging Assistant" LoaderLock "reports an error message" Message= Managed Debugging Assistant "LoaderLock": "Attempting to execute managed code within the OS loader lock. Do not attempt to run managed code within DllMain or image initialization functions as this can cause the application to hang." You can use the shortcut Ctrl+ Alt+ E. Change Managed Debugging Assistants -> Remove the selected state of LoaderLock.