Не рендерится прямоугольник DirectX C#

Делаю аркадный космический 3D симулятор на DirectX C# средствами SharpDX. Основную часть сделал, осталось только реализовать интерфейс пользователя. По требованию HUD необходимо реализовать средствами Direct3D. HUD элементарный: должен включать в себя главное меню, представленное задним фоном(прямоугольник, растянутый на весь экран) и две прямоугольных кнопки "Начать игру" и "Выйти из игры". Понятно, что нужно просто нарисовать три прямоугольника, которые будут иметь позицию, размер и определённый цвет(с текстурами решил не заморачиваться и просто покрасить их в цвета). Я создал вершинный шейдер:

cbuffer ConstantBuffer : register(b0)
{
    matrix worldViewProjectionMatrix;
};

struct VertexInput
{
    float2 position : POSITION; 
    float4 color : COLOR;
};

struct VertexOutput
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VertexOutput main(VertexInput input)
{
    VertexOutput output;

    // Преобразование позиции вершины
    output.position = mul(float4(input.position, 0.0f, 1.0f), worldViewProjectionMatrix); 

    // Передача цвета вершины
    output.color = input.color;

    return output;
}

И пиксельный шейдер

struct PixelInput
{
    float4 position : SV_POSITION; // Позиция пикселя в пространстве экрана
    float4 color : COLOR; // Цвет пикселя
};

float4 main(PixelInput input) : SV_Target
{
    return input.color;
}

Далее создал класс HUDRenderer:

using SharpDX;
using SharpDX.D3DCompiler;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using System;
using System.Runtime.InteropServices;
using static SimpleDXApp.Renderer;
using Buffer = SharpDX.Direct3D11.Buffer;

namespace SimpleDXApp
{
    public class HUDRenderer : IDisposable
    {
        private DirectX3DGraphics _directX3DGraphics;
        private DeviceContext _deviceContext;

        private VertexShader _vertexShader;
        private PixelShader _pixelShader;
        private ShaderSignature _shaderSignature;
        private InputLayout _inputLayout;

        [StructLayout(LayoutKind.Sequential)]
        public struct VertexDataStruct
        {
            public Vector2 position;
            public Color4 color;
        }

        public HUDRenderer(DirectX3DGraphics directX3DGraphics)
        {
            _directX3DGraphics = directX3DGraphics;
            _deviceContext = _directX3DGraphics.DeviceContext;

            // Компиляция и создание вершинного шейдера
            var vertexShaderByteCode = ShaderBytecode.CompileFromFile("HUD/hud_vertex.hlsl", "main", "vs_5_0");
            _vertexShader = new VertexShader(_directX3DGraphics.Device, vertexShaderByteCode);
            _shaderSignature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
            _inputLayout = new InputLayout(_directX3DGraphics.Device, _shaderSignature, new[]
            {
                new InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32_Float, 0, 0),
                new InputElement("COLOR", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 8, 0)
            });
            _deviceContext.InputAssembler.InputLayout = _inputLayout;
            _deviceContext.VertexShader.Set(_vertexShader);

            // Компиляция и создание пиксельного шейдера
            var pixelShaderByteCode = ShaderBytecode.CompileFromFile("HUD/hud_pixel.hlsl", "main", "ps_5_0");
            _pixelShader = new PixelShader(_directX3DGraphics.Device, pixelShaderByteCode);
            _deviceContext.PixelShader.Set(_pixelShader);

            // Очистка ресурсов шейдеров
            Utilities.Dispose(ref vertexShaderByteCode);
            Utilities.Dispose(ref pixelShaderByteCode);
        }

        public void Dispose()
        {
            // Освобождение ресурсов
            Utilities.Dispose(ref _inputLayout);
            Utilities.Dispose(ref _shaderSignature);
            Utilities.Dispose(ref _vertexShader);
            Utilities.Dispose(ref _pixelShader);
        }

        public void BeginRender()
        {
            _directX3DGraphics.ClearBuffers(Color.Transparent);
        }

        public void EndRender()
        {
            _directX3DGraphics.SwapChain.Present(1, PresentFlags.Restart);
        }

        public void DrawRectangle(Vector2 position, Vector2 size, Color4 color)
        {
            VertexDataStruct[] vertices = new VertexDataStruct[4]
            {
                new VertexDataStruct { position = new Vector2(position.X, position.Y), color = color },
                new VertexDataStruct { position = new Vector2(position.X + size.X, position.Y), color = color },
                new VertexDataStruct { position = new Vector2(position.X, position.Y - size.Y), color = color },
                new VertexDataStruct { position = new Vector2(position.X + size.X, position.Y - size.Y), color = color }
            };

            // Создание вершинного буфера
            using (var vertexBuffer = Buffer.Create(_directX3DGraphics.Device, BindFlags.VertexBuffer, vertices))
            {
                // Установка вершинного буфера
                _deviceContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, Utilities.SizeOf<VertexDataStruct>(), 0));

                // Установка примитивного типа
                _deviceContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleStrip;

                // Отрисовка прямоугольника
                _deviceContext.Draw(vertices.Length, 0);
            }
        }
    }
}

В классе Game создал экземпляр этого класса и попытался нарисовать прямоугольник следующим образом:

_hudRenderer.BeginRender();
_hudRenderer.DrawRectangle(new Vector2(10, 10), new Vector2(800, 600), new Color4(1, 1, 0, 1));
_hudRenderer.EndRender();

Но при запуске вижу просто черный экран, ничего не рисуется. Но почему? Понимаю, что код, может, неграмотный и надо было бы создать класс для элементов HUD, но вопрос в другом: почему не рендерится? Скидываю полный код класса Game:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Effects;
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using Device = SharpDX.Direct3D11.Device;
using Buffer = SharpDX.Direct3D11.Buffer;
using SharpDX.DirectInput;
using SharpDX.Windows;
using ObjLoader.Loader.Loaders;
using static SimpleDXApp.Renderer;
using System.Windows.Media.Media3D;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Timers;
using Rectangle = SharpDX.Rectangle;
using SharpDX.Direct2D1;
using ObjLoader.Loader.Data.VertexData;
using SharpDX.DXGI;
using System.Drawing;
using RectangleF = SharpDX.RectangleF;
using FeatureLevel = SharpDX.Direct3D.FeatureLevel;
using DeviceContext = SharpDX.Direct3D11.DeviceContext;
using Color = SharpDX.Color;
using SharpDX.D3DCompiler;
using System.Numerics;
using Vector2 = SharpDX.Vector2;
using Vector3 = SharpDX.Vector3;
using Vector4 = SharpDX.Vector4;
using NAudio.CoreAudioApi;
using System.Windows;

namespace SimpleDXApp
{
    public class Game : IDisposable
    {
        private RenderForm _renderForm;
        private List<MeshObject> _planets = new List<MeshObject>(); //планеты
        private List<Vector4> _planetVelocities = new List<Vector4>();
        private List<MeshObject> _asteroids = new List<MeshObject>();
        private float _timeSinceLastPlanet = 0.0f;
        private float _planetSpawnInterval = 5.0f; // Интервал появления планет в секундах
        private Camera _camera;
        Texture _squareAntiprismTexture; //Текстура планеты
        Texture _backgroundTexture; //Текстура фона
        Texture _boarderTexture; //Текстура границы
        private Texture _asteroidTexture; //Текстура астероида 
        protected DirectX3DGraphics _directX3DGraphics;
        protected DirectX3DGraphics _directX3DGraphicsHUD;
        protected Renderer _renderer;
        private TimeHelper _timeHelper;
        private DInput _dInput;
        private float sceneSize = 10000.0f; //Размер сцены
        private MeshObject _spaceship;
        private Texture _spaceshipTexture;
        private BoundingSphere _spaceshipCollider;
        private MeshObject _spaceshipColliderObject;
        private BoundingSphere _planetCollider;
        private BoundingSphere _asteroidCollider;
        private float movementSpeed = 3f;
        private bool canControlSpaceship = true;
        private Vector3 spaceshipVelocity = Vector3.Zero;
        private MeshObject _bullet;
        private BoundingSphere _bulletCollider;
        private Texture _bulletTexture;
        static bool accelerationAvailable = false;

        private AudioManager audioManager; //Музыка
        private bool audio = false; //Звук полёта

        MeshObject _skybox;

        List<MeshObject> _colliders = new List<MeshObject>();                          
        List<BoundingSphere> _planetColliders = new List<BoundingSphere>();            
        List<BoundingSphere> _asteroidColliders = new List<BoundingSphere>();         
        List<MeshObject> _planetCollidersObjects = new List<MeshObject>();               

        //Физические константы
        private const float planetMass = 9500000000000000f;
        private const float asteroidMass = 15f;
        private const float spaceshipMass = 1f;

        //HUD
        private HUDRenderer _hudRenderer;

        //Звуковые ффекты
        private AudioManager asteroidDestruction;

        //Визуальные эффекты

        public Game()
        {
            _renderForm = new RenderForm("FPS: ");
            _renderForm.WindowState = FormWindowState.Maximized;
            _renderForm.FormBorderStyle = FormBorderStyle.None;

            _dInput = new DInput(_renderForm);
            _renderForm.UserResized += RenderFormResizedCallback;
            _directX3DGraphics = new DirectX3DGraphics(_renderForm);
            _directX3DGraphicsHUD = new DirectX3DGraphics(_renderForm);
            _renderer = new Renderer(_directX3DGraphics);
            _renderer.CreateConstantBuffer();
            _hudRenderer = new HUDRenderer(_directX3DGraphicsHUD);
            Loader loader = new Loader(_directX3DGraphics);
            _backgroundTexture = loader.LoadTextureFromFile("images/space2.jpg", _renderer.AnisotropicSampler);
            _boarderTexture = loader.LoadTextureFromFile("images/boarder.png", _renderer.AnisotropicSampler);
            _spaceshipTexture = loader.LoadTextureFromFile("images/spaceship.jpg", _renderer.AnisotropicSampler);
            _squareAntiprismTexture = loader.LoadTextureFromFile("images/planet.png", _renderer.AnisotropicSampler);
            _asteroidTexture = loader.LoadTextureFromFile("images/asteroid.png", _renderer.AnisotropicSampler);
            _bulletTexture = loader.LoadTextureFromFile("images/laser.jpg", _renderer.AnisotropicSampler);
            _camera = new Camera(new Vector4(0.0f, 2.0f, -3.1f, 1.0f));
            
            _timeHelper = new TimeHelper();
            loader.Dispose();
            loader = null;

            Background();
            AddSpaceship();
            AccelerationTimer();

            audioManager = new AudioManager("Assets/Sounds/BackgroundMusic.mp3");
            audioManager.Play();
            //Cursor.Hide();
        }

        public void RenderFormResizedCallback(object sender, EventArgs args)
        {
            _directX3DGraphics.Resize();
            _camera.Aspect = _renderForm.ClientSize.Width /
                (float)_renderForm.ClientSize.Height;
        }

        private bool _firstRun = true;
        private bool _renderGameContent = false;

        public void RenderLoopCallback()
        {
            FormOptions();

            if (_renderGameContent)
            {
                // Вызов методов для обновления игровой логики
                Collisions();
                ApplyGravity();
                SpaceShipControl();
                PlanetSpawner();
                Shot();
                if (accelerationAvailable) UseAcceleration();

                // Рендеринг игрового контента
                Render();
            }
            else
            {
                // Рендеринг только HUD
                DrawHUD();
            }
        }

        private void DrawHUD()
        {
            _hudRenderer.BeginRender();
            _hudRenderer.DrawRectangle(new Vector2(10, 10), new Vector2(800, 600), new Color4(1, 1, 0, 1));
            _hudRenderer.EndRender();
        }

        private void FormOptions()
        {
            _dInput.UpdateKeyboardState();
            _dInput.UpdateMouseState();
            if (_firstRun)
            {
                RenderFormResizedCallback(this, EventArgs.Empty);
                _firstRun = false;
            }
            _timeHelper.Update();
            _renderForm.Text = "FPS: ";
            if (_dInput.KeyboardState.IsPressed(Key.Escape)) _renderForm.Close();
        }
        public void Run()
        {
            RenderLoop.Run(_renderForm, RenderLoopCallback);
        }

        public void Dispose()
        {
            //_bullet.Dispose();
            foreach (var asteroid in _asteroids)
            {
                asteroid.Dispose();
            }
            _spaceship.Dispose();
            _squareAntiprismTexture.Dispose();
            _renderer.Dispose();
            _hudRenderer.Dispose();
            _directX3DGraphics.Dispose();
        }

        //Остальные методы, не имеющие отношения к HUD не были включены в код

    }
}

Ответы (0 шт):