Device.DrawIndexedPrimitive не рисует квадрат - PullRequest
0 голосов
/ 13 октября 2019

Я пытаюсь написать какой-нибудь класс, чтобы нарисовать оверлей в игре. И столкнувшись с проблемой, прямое 3D-устройство не рисует примитивы. Пытаясь решить проблему самостоятельно, я решил написать простой проект, который делает то же самое, но без захвата конца сцены. Я написал небольшой код, который выполняет те же действия, что и мне, в оверлейном классе визуализации. Этот код воспроизвел ту же проблему. Почему бы не нарисовать простой квадрат, состоящий из 2 примитивов треугольников?

Ниже приведен проблемный код:

public class Program
{

    [STAThread]
    private static void Main()
    {
        RenderForm form = new RenderForm("Simple Direct3D 9 Window");

        Direct3D direct3D = new Direct3D();
        Device device = new Device
        (
            direct3D,
            0,
            DeviceType.Hardware,
            form.Handle,
            CreateFlags.HardwareVertexProcessing,
            new PresentParameters(form.ClientSize.Width, form.ClientSize.Height)
            {
                BackBufferFormat = Format.A8R8G8B8
            }
        );

        (CustomVertex[] vertices, ushort[] indexes) = CustomVertex.MakeSquare
        (
            new Vector2(100f, 100f),
            new Size2F(100f, 120f),
            Color.White
        );

        VertexBuffer vertexBuffer = new VertexBuffer
        (
            device,
            Utilities.SizeOf(vertices),
            Usage.WriteOnly,
            VertexFormat.PositionRhw | VertexFormat.Diffuse,
            Pool.Managed
        );

        vertexBuffer
            .Lock(0, 0, LockFlags.None)
            .WriteRange(vertices);

        vertexBuffer.Unlock();

        IndexBuffer indexBuffer = new IndexBuffer
        (
            device,
            Utilities.SizeOf(indexes),
            Usage.WriteOnly,
            Pool.Managed,
            true
        );

        indexBuffer
            .Lock(0, 0, LockFlags.None)
            .WriteRange(indexes);

        indexBuffer.Unlock();

        RenderLoop.Run(form, () =>
        {
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1f, 0);
            device.BeginScene();

            device.VertexFormat = VertexFormat.PositionRhw | VertexFormat.Diffuse;
            device.SetStreamSource(0, vertexBuffer, Utilities.SizeOf<CustomVertex>(), 0);

            device.Indices = indexBuffer;

            device.DrawIndexedPrimitive(PrimitiveType.TriangleStrip, 0, 0, 4, 0, 2);

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

        indexBuffer.Dispose();
        vertexBuffer.Dispose();
        device.Dispose();
        direct3D.Dispose();
        form.Dispose();
    }

    [StructLayout(LayoutKind.Sequential)]
    struct CustomVertex
    {
        public float X, Y, Z, Rhw;
        public uint Color;

        public CustomVertex(float x, float y, Color color, float z = 0f, float w = 1f)
        {
            X = x;
            Y = y;
            Z = z;
            Rhw = w;

            Color = (color.A & 0xffU) << 24 | ((color.R & 0xffU) << 16) | ((color.G & 0xffU) << 8) | (color.B & 0xffU);
        }

        public static (CustomVertex[], ushort[]) MakeSquare(Vector2 pos, Size2F size, Color color)
        {
            return
            (
                new[]
                {
                    new CustomVertex(pos.X, pos.Y, color),
                    new CustomVertex(pos.X + size.Width, pos.Y, color),
                    new CustomVertex(pos.X + size.Width, pos.Y + size.Height, color),
                    new CustomVertex(pos.X, pos.Y + size.Height, color),
                },
                new ushort[] { 0, 1, 3, 1, 2, 3 }
            );
        }
    }
}
...