1

我正在尝试处理正在调整大小的程序窗口,而我在下面拼凑的(我认为效率低下的)代码似乎可以解决问题。

有没有更好的方法来做到这一点,最好是在调整窗口大小时不会产生卡顿并且不会持续使用 12-17% 的 CPU 的方法?我还怀疑MessagePump.Run可能会在再次完成设备设置之前以某种方式运行form.Resize,并引发错误。

谢谢!

using System;
using System.Drawing;
using System.Windows.Forms;

using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;

namespace SlimDX_1
{
    struct Vertex
    {
        public Vector4 Position;
        public int Color;
    }

    static class Program
    {
        private static VertexBuffer vertices;
        private static Device device;
        private static RenderForm form;
        private static PresentParameters present;
        private static VertexDeclaration vertexDecl;
        private static VertexElement[] vertexElems;

        private static bool wasMinimized = false;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            form = new RenderForm("Tutorial 1: Basic Window");

            init();

            form.Resize += (o, e) =>
                {
                    if (form.WindowState == FormWindowState.Minimized)
                    {
                        foreach (var item in ObjectTable.Objects)
                        {
                            item.Dispose();
                        }
                        wasMinimized = true;
                    }
                    else
                    {
                        foreach (var item in ObjectTable.Objects)
                        {
                            item.Dispose();
                        }
                        init();

                        device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);
                        device.SetRenderState(RenderState.CullMode, Cull.None);

                        present.BackBufferHeight = form.ClientSize.Height;
                        present.BackBufferWidth = form.ClientSize.Width;

                        device.Reset(present);
                    }
                };

            MessagePump.Run(form, () =>
            {
                if (form.WindowState == FormWindowState.Minimized)
                {
                    return;
                }

                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
                device.BeginScene();

                device.SetStreamSource(0, vertices, 0, 20); // 20 is the size of each vertex
                device.VertexDeclaration = vertexDecl;
                device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

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

            foreach (var item in ObjectTable.Objects)
            {
                item.Dispose();
            }
        }

        private static void init()
        {
            present = new PresentParameters();
            //present.EnableAutoDepthStencil = false;
            //present.BackBufferCount = 1;
            //present.SwapEffect = SwapEffect.Discard;
            present.Windowed = true;
            present.BackBufferHeight = form.ClientSize.Height;
            present.BackBufferWidth = form.ClientSize.Width;
            //present.BackBufferFormat = Format.Unknown;

            device = new Device(new Direct3D(), 0, DeviceType.Hardware, form.Handle, CreateFlags.HardwareVertexProcessing, present);

            vertices = new VertexBuffer(device, 3 * 20, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
            vertices.Lock(0, 0, LockFlags.None).WriteRange(new Vertex[]
            {
                new Vertex() { Color = Color.Red.ToArgb(), Position = new Vector4(400.0f, 100.0f, 0.5f, 1.0f) },
                new Vertex() { Color = Color.Blue.ToArgb(), Position = new Vector4(650.0f, 500.0f, 0.5f, 1.0f) },
                new Vertex() { Color = Color.Green.ToArgb(), Position = new Vector4(150.0f, 500.0f, 0.5f, 1.0f) }
            });
            vertices.Unlock();

            // specifies the layout of the vertexes
            vertexElems = new VertexElement[]
            {
                new VertexElement(0, 0, DeclarationType.Float4, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0),
                new VertexElement(0, 16, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
                VertexElement.VertexDeclarationEnd
            };

            vertexDecl = new VertexDeclaration(device, vertexElems);
        }
    }
}
4

1 回答 1

1

调整窗口大小时,您将远远超出您需要做的事情。您正在释放您创建的每个 DirectX 对象,包括图形设备,然后重新创建所有内容。这将需要相对较长的时间,这就是您看到性能问题的原因。

事实上,您的任何对象都不需要被释放。只需调用设备上的 Reset() 函数即可重新创建后缓冲区以匹配新的窗口大小。查看有关窗口大小调整的一些本机 Direct3D9 教程,以了解该过程的一般工作方式。

于 2012-04-25T05:24:31.370 回答