基于DirectX和C#的三维显示控件实现

一、控件架构设计

graph TD A[三维显示控件] --> B[设备管理] A --> C[场景管理] A --> D[输入处理] B --> B1(初始化Direct3D) B --> B2(设备重置) C --> C1(地形生成) C --> C2(模型加载) D --> D1(摄像机控制) D --> D2(鼠标交互)

二、核心代码实现

1. 控件初始化(XSceneControl.cs)

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

public class XSceneControl : Panel
{
    private Device device;
    private PresentParameters pres;
    private CustomVertex.PositionColored[] verts;
    
    protected override void OnPaint(PaintEventArgs e)
    {
        Render();
    }

    public void InitializeDevice()
    {
        pres = new PresentParameters();
        pres.Windowed = true;
        pres.SwapEffect = SwapEffect.Discard;
        pres.EnableAutoDepthStencil = true;
        pres.AutoDepthStencilFormat = DepthFormat.D16;

        device = new Device(0, DeviceType.Hardware, this, 
            CreateFlags.HardwareVertexProcessing, pres);
        
        device.RenderState.CullMode = Cull.None;
        device.RenderState.Lighting = false;
    }

    public void CreateVertexBuffer()
    {
        verts = new CustomVertex.PositionColored[36];
        // 初始化顶点数据(示例:立方体)
        // ... 顶点坐标与颜色赋值
        using (VertexBuffer vb = new VertexBuffer(
            typeof(CustomVertex.PositionColored), 
            verts.Length, 
            device, 
            Usage.Dynamic | Usage.WriteOnly, 
            CustomVertex.PositionColored.Format, 
            Pool.Default))
        {
            vb.Lock(0, 0, LockFlags.None);
            Buffer.MemoryCopy(verts, vb.DataPointer, verts.Length * 20, verts.Length * 20);
            vb.Unlock();
        }
    }
}

2. 场景渲染(XSceneControl.cs)

public void Render()
{
    if (device == null) return;

    device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, 
        Color.CornflowerBlue, 1.0f, 0);
    
    device.BeginScene();
    
    // 设置摄像机
    Matrix view = Matrix.LookAtLH(
        new Vector3(0, 0, -5), 
        new Vector3(0, 0, 0), 
        new Vector3(0, 1, 0));
    device.Transform.View = view;

    // 绘制几何体
    device.SetStreamSource(0, vb, 0, CustomVertex.PositionColored.SizeInBytes);
    device.VertexFormat = CustomVertex.PositionColored.Format;
    device.DrawPrimitives(PrimitiveType.TriangleList, 0, verts.Length / 3);

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

3. 摄像机控制(CameraController.cs)

public class CameraController
{
    private Vector3 position = new Vector3(0, 0, -5);
    private Vector3 target = Vector3.Zero;
    private float yaw = 0.0f, pitch = 0.0f;

    public Matrix GetViewMatrix()
    {
        return Matrix.LookAtLH(position, target, Vector3.UnitY);
    }

    public void Rotate(float yawDelta, float pitchDelta)
    {
        yaw += yawDelta;
        pitch += pitchDelta;
        pitch = Math.Max(-Math.PI/2, Math.Min(Math.PI/2, pitch));
    }

    public void Update()
    {
        Matrix rotation = Matrix.RotationYawPitchRoll(yaw, pitch, 0);
        Vector3 forward = Vector3.TransformNormal(Vector3.UnitZ, rotation);
        position = target + forward * 5.0f;
    }
}

三、功能扩展实现

1. 地形生成(TerrainBuilder.cs)

public class TerrainBuilder
{
    public static Mesh CreateTerrain(Device device, string heightMapPath)
    {
        Texture heightMap = TextureLoader.FromFile(device, heightMapPath);
        int width = heightMap.GetSize().Width;
        int depth = heightMap.GetSize().Height;

        CustomVertex.PositionNormalTextured[] vertices = new CustomVertex.PositionNormalTextured[width * depth];
        
        // 生成顶点数据(高度图采样)
        for (int z = 0; z < depth; z++)
        {
            for (int x = 0; x < width; x++)
            {
                float height = heightMap.GetPixel(x, z).R / 255.0f * 10.0f;
                vertices[x + z * width] = new CustomVertex.PositionNormalTextured(
                    new Vector3(x, height, z),
                    Vector3.Up,
                    new Vector2((float)x/width, (float)z/depth));
            }
        }

        Mesh mesh = new Mesh(width, depth, MeshFlags.Managed, CustomVertex.PositionNormalTextured.Format, device);
        mesh.SetVertexBufferData(vertices, 0, 0, LockFlags.None);
        return mesh;
    }
}

2. 模型加载(ModelLoader.cs)

public class ModelLoader
{
    public static Mesh LoadXFile(Device device, string filePath)
    {
        Mesh mesh = Mesh.FromFile(filePath, MeshFlags.SystemMemory, device);
        ExtendedMaterial[] materials;
        mesh.Materials = new MaterialCollection();
        
        using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            BinaryReader br = new BinaryReader(fs);
            // 解析.x文件材质信息
            // ... 实现材质加载逻辑
        }
        
        return mesh;
    }
}

四、交互控制实现

1. 鼠标事件处理(XSceneControl.cs)

protected override void OnMouseDown(MouseEventArgs e)
{
    lastMousePos = e.Location;
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        int dx = e.X - lastMousePos.X;
        int dy = e.Y - lastMousePos.Y;
        
        camera.Rotate(dx * 0.01f, dy * 0.01f);
        Invalidate();
    }
    lastMousePos = e.Location;
}

protected override void OnMouseWheel(MouseEventArgs e)
{
    camera.Zoom(e.Delta > 0 ? 0.1f : -0.1f);
    Invalidate();
}

五、部署与优化

1. 项目配置

<!-- app.config -->
<configuration>
  <system.diagnostics>
    <switches>
      <add name="DirectXDebug" value="4"/>
    </switches>
  </system.diagnostics>
</configuration>

2. 性能优化策略

  • 顶点缓存优化:使用VertexFormat压缩顶点数据

  • LOD技术:根据视距动态调整地形细节层级

  • 多线程渲染:分离渲染线程与逻辑线程

// 渲染线程示例
private void RenderThread()
{
    while (isRunning)
    {
        lock (renderLock)
        {
            device.BeginScene();
            // 执行渲染命令
            device.EndScene();
        }
        Thread.Sleep(16); // 约60FPS
    }
}

参考代码 基于directx和c#的三维显示控件 www.youwenfan.com/contentcnr/111985.html

六、扩展功能建议

  1. 着色器支持

    添加HLSL着色器实现动态光照和特效

    // 顶点着色器
    float4 VS(float3 pos : POSITION, float2 tex : TEXCOORD) : POSITION
    {
        return mul(float4(pos, 1.0), WorldViewProj);
    }
    
  2. 粒子系统

    实现烟雾、火焰等特效

    public class ParticleSystem
    {
        private List<Particle> particles = new();
    
        public void Update(float deltaTime)
        {
            foreach (var p in particles)
            {
                p.Position += p.Velocity * deltaTime;
                p.LifeTime -= deltaTime;
            }
            particles.RemoveAll(p => p.LifeTime <= 0);
        }
    }
    
  3. 物理引擎集成

    使用BulletSharp实现碰撞检测

    using BulletSharp;
    
    public class PhysicsWorld
    {
        private DiscreteDynamicsWorld world;
    
        public void Initialize()
        {
            CollisionConfiguration config = new DefaultCollisionConfiguration();
            Dispatcher dispatcher = new Dispatcher(config);
            world = new DiscreteDynamicsWorld(dispatcher, null, null, config);
        }
    }
    

七、调试技巧

  1. 错误处理

    try
    {
        device.Reset(pres);
    }
    catch (DirectXException ex)
    {
        Debug.WriteLine($"DirectX Error: {ex.Message}");
    }
    
  2. 性能监控

    PerformanceCounter gpuCounter = new PerformanceCounter(
        "GPU", "Utilization Percentage", "_Total");
    float gpuUsage = gpuCounter.NextValue();
    
posted @ 2026-02-11 16:24  风一直那个吹  阅读(3)  评论(0)    收藏  举报