1

サイズ変更されているプログラムウィンドウを処理しようとしていますが、以下で一緒に使用した(非効率的だと思う)コードでうまくいくようです。

これを行うためのより良い方法はありますか?できれば、ウィンドウのサイズを変更するときにスタッターを作成せず、CPUの12〜17%を常に使用しない方法はありますか?また、デバイスのセットアップ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 に答える