DrawUserIndexedPrimitives: почему индексы должны быть короткими, а не int? - PullRequest
3 голосов
/ 17 августа 2011

Существует два типа перегрузок DrawUserIndexedPrimitive: Те, которые принимают 16-битные индексы и Те, которые принимают 32-битные индексы .

При использовании 16-битных индексов все работает нормально. При использовании 32-битных индексов я получаю InvalidOperationException с «полезным» текстом ошибки An unexpected error has occurred (без внутренних исключений) при вызове DrawUserIndexedPrimitive. Когда я включаю «Отладку неуправляемого кода» в свойствах проекта, я получаю строки

Исключение первого шанса в 0x75a5b9bc в DrawUserPrimitives.exe: исключение Microsoft C ++: длинное место в памяти 0x0032e6b4 ..
Исключение первого шанса в 0x75a5b9bc в DrawUserPrimitives.exe: исключение Microsoft C ++: длинный в ячейке памяти 0x0032e728 ..

в окне отладки перед тем, как сгенерировано исключение.

Почему это происходит? Поскольку обе перегрузки доступны, я бы предположил, что оба сработают (или, по крайней мере, сгенерируют значимое исключение, если поддерживается только одна из них). Вот полный пример минимальной программы, которую можно использовать для воспроизведения этой проблемы. Я использую XNA 3.0.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

public class GameTest : Microsoft.Xna.Framework.Game
{
    static void Main(string[] args)
    {
        using (var game = new GameTest())
        {
            game.Run();
        }
    }

    GraphicsDeviceManager manager;

    public GameTest() { manager = new GraphicsDeviceManager(this); }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.SteelBlue);
        GraphicsDevice.VertexDeclaration = new VertexDeclaration(GraphicsDevice, VertexPositionColor.VertexElements);

        var basicEffect = new BasicEffect(GraphicsDevice, null);
        basicEffect.VertexColorEnabled = true;
        basicEffect.View = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up);
        basicEffect.Projection = Matrix.CreateOrthographicOffCenter(-1, 2, 2, -1, 1.0f, 1000.0f);

        // two simple points
        var pointList = new VertexPositionColor[] {
            new VertexPositionColor(new Vector3(0,0,0), Color.White),
            new VertexPositionColor(new Vector3(0,1,0), Color.White)
        };

        // one simple line between those two points
        var lineListIndices = new short[] { 0, 1 };      // works fine
        // var lineListIndices = new int[] { 0, 1 };     // causes exception below

        basicEffect.Begin();
        foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
        {
            pass.Begin();
            GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
                PrimitiveType.LineList, pointList, 0, 2, 
                lineListIndices, 0, 1);  // exception occurs here
            pass.End();
        }
        basicEffect.End();

        base.Draw(gameTime);
    }
}

1 Ответ

2 голосов
/ 19 августа 2011

Загадочное сообщение об ошибке, похоже, ошибка в XNA 3.0 (спасибо Эндрю за подсказку). Запуск кода (немного измененного) в XNA 4.0 приводит к более полезному сообщению об ошибке (NotSupportedException):

Профиль XNA Framework Reach не поддерживает 32-битные индексы. Используйте IndexElementSize.SixteenBits или тип размером два байта.

Это имеет смысл, поскольку моя видеокарта, похоже, не поддерживает профиль HiDef, который будет поддерживать 32-битные индексы.

...