Перепутанные треугольники при использовании VertexPositionColorTexture с BasicEffect

#c# #visual-studio-2010 #xna

#c# #visual-studio-2010 #xna

Вопрос:

изображение проблемы

Я использовал руководство Microsoft по BasicEffect здесь и пример кода здесь: go.microsoft.com/fwlink/?LinkId=198921 и все заработало нормально. Затем я изменил все, чтобы использовать vertexPositionNormalTexture, добавил несколько небольших методов, помогающих с текстурой, и смог отлично отобразить текстурированный куб. Я также заставил куб немного вращаться. Далее я хотел попробовать использовать vertexPositionNormalTexture. К сожалению, я получил это изображение вместо куба. Вот некоторые фрагменты моего кода, которые содержат серьезные изменения.

Метод рисования

  protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.SteelBlue);

            RasterizerState rasterizerState1 = new RasterizerState();
            //backface culling
            rasterizerState1.CullMode = CullMode.None;
            //turn off texture blurring
            graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;


            graphics.GraphicsDevice.RasterizerState = rasterizerState1;
            foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
            {
                pass.Apply();
                graphics.GraphicsDevice.DrawPrimitives(
                    PrimitiveType.TriangleList, 
                    0, 
                    12
                );
            } 

            base.Draw(gameTime);
        }
  

Часть метода, который устанавливает вершины

 private void InitializeCube()
    {

        Vector3 topLeftFront = new Vector3(-1.0f, 1.0f, 1.0f);
        Vector3 bottomLeftFront = new Vector3(-1.0f, -1.0f, 1.0f);
        Vector3 topRightFront = new Vector3(1.0f, 1.0f, 1.0f);
        Vector3 bottomRightFront = new Vector3(1.0f, -1.0f, 1.0f);
        Vector3 topLeftBack = new Vector3(-1.0f, 1.0f, -1.0f);
        Vector3 topRightBack = new Vector3(1.0f, 1.0f, -1.0f);
        Vector3 bottomLeftBack = new Vector3(-1.0f, -1.0f, -1.0f);
        Vector3 bottomRightBack = new Vector3(1.0f, -1.0f, -1.0f);

        Vector2 textureTopLeft = new Vector2(0.0f, 0.0f);
        Vector2 textureTopRight = new Vector2(.25f, 0.0f);
        Vector2 textureBottomLeft = new Vector2(0.0f, .25f);
        Vector2 textureBottomRight = new Vector2(.25f, .25f);

        Color frontColor = new Color(255, 255, 255);
        Color backColor = new Color(255, 0, 0);
        Color topColor = new Color(0, 255, 0);
        Color bottomColor = new Color(0, 0, 255);
        Color leftColor = new Color(0, 255, 255);
        Color rightColor = new Color(0, 0, 0);

        // Front face.
        cubeVertices[0] =
            new VertexPositionColorTexture(
            topLeftFront, frontColor, GetTexPos(2));
        cubeVertices[1] =
            new VertexPositionColorTexture(
            bottomLeftFront, frontColor, GetTexPos(2)   textureBottomLeft);
        cubeVertices[2] =
            new VertexPositionColorTexture(
            topRightFront, frontColor, GetTexPos(2)   textureTopRight);
        cubeVertices[3] =
            new VertexPositionColorTexture(
            bottomLeftFront, frontColor, GetTexPos(2)   textureBottomLeft);
        cubeVertices[4] =
            new VertexPositionColorTexture(
            bottomRightFront, frontColor, GetTexPos(2)   textureBottomRight);
        cubeVertices[5] =
            new VertexPositionColorTexture(
            topRightFront, frontColor, GetTexPos(2)   textureTopRight);
  

Инициализация BasicEffect

 private void InitializeEffect()
    {
        basicEffect = new BasicEffect(graphics.GraphicsDevice);


        basicEffect.World = worldMatrix;
        basicEffect.View = viewMatrix;
        basicEffect.Projection = projectionMatrix;

        //basicEffect.EnableDefaultLighting
    }
  

LoadContent

 protected override void LoadContent()
    {
        canyonTexture = Content.Load<Texture2D>("CanyonTexture");
        textureSheetWidth = canyonTexture.Width / 16;
        InitializeTransform();
        InitializeEffect();
        basicEffect.TextureEnabled = true;
        basicEffect.VertexColorEnabled = true;
        basicEffect.Texture = canyonTexture;

        InitializeCube();

    }
  

Настройка VertexBuffer

 private void CreateVertexBuffer()
    {
        vertexDeclaration = new VertexDeclaration(new VertexElement[]
            {
                new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
                new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0),
                new VertexElement(24, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
            });

        vertexBuffer = new VertexBuffer(
            graphics.GraphicsDevice,
            vertexDeclaration,
            number_of_vertices,
            BufferUsage.None
            );


        cubeVertices = new VertexPositionColorTexture[number_of_vertices];
        InitializeCube();


        vertexBuffer.SetData<VertexPositionColorTexture>(cubeVertices);

        graphics.GraphicsDevice.SetVertexBuffer(vertexBuffer);
    }


    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        CreateVertexBuffer();

        base.Initialize();
    }
  

Комментарии:

1. Хм, этот вопрос был бы лучше на gamedev.stackexchange.com имхо.

2. Спасибо, если я не получу решение, я, вероятно, отправлю его туда через день или около того.

3. Да, это действительно стоит посмотреть, если вы не получите ответа, я всегда получаю ответы на свои вопросы XNA там.

4. Архимед был бы в смятении.

Ответ №1:

По сути, ваше объявление вершины неверно.

A Color имеет ширину всего четыре байта. Таким образом, смещение следующего элемента текстурных координат должно быть 16, а не 24.

Однако вам даже не нужно создавать объявление вершины для этого в XNA 4.0. Просто передайте VertexPositionColorTexture.VertexDeclaration or typeof(VertexPositionColorTexture) вашему VertexBuffer конструктору.

Здесь есть сообщение в блоге, в котором объясняется, как все это работает.

Комментарии:

1. Спасибо, теперь это работает отлично! Я подозревал, что что-то не так с объявлением вершины, но я не мог понять, что. Кажется, что всякий раз, когда у меня возникает какая-то проблема, всегда есть встроенная функциональность XNA, которая делает все намного проще. Проблема на самом деле в осознании того, что это есть!