【问题标题】:Texturing primitives with custom vertex declaration使用自定义顶点声明纹理基元
【发布时间】:2014-09-23 00:13:14
【问题描述】:

我在使用 XNA 4.0 时遇到问题,甚至无法通过 Google 搜索。它出现在我的主项目以及我的测试项目中,这是一个非常简单的版本,可以减少不必要的代码。

我需要使用我自己的自定义顶点声明并使用它来绘制带纹理的图元(或者为什么不使用模型)。

使用 BasicEffect 和任何内置的顶点声明(如 VertexPositionColorTexture)可以很好地绘制和纹理...但是如果我将 BasicEffect 与我的自定义顶点声明一起使用,那么纹理无法正确绘制到底有什么问题?我很想将所有内置类型的组合保存在一个 VD 中。我唯一的解决方法是我应该制作一个新的顶点/像素着色器,但这有帮助吗?如果可以,我该怎么做?

我尝试上传图片来描述,但我需要至少 10 个声望,所以我会用文字解释: 使用我的自定义 VD,我的正方形(和任何其他形状)对象的纹理似乎是平铺的,而不是缩放/适合的。此外,当我旋转对象时,纹理不会旋转。

这是我的自定义顶点声明:

namespace WindowsGame2
{
  public struct VertexPositionNormalColorTexture : IVertexType
  {
  public Vector3 Position;
  public Vector3 Normal;
  public Color Color;
  public Vector2 TextureCoordinate;

  VertexDeclaration IVertexType.VertexDeclaration
  {
     get { return VertexDeclaration; }
  }

  public readonly static VertexDeclaration VertexDeclaration = 
     new VertexDeclaration(
     new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
     new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector3, VertexElementUsage.Normal, 0),
     new VertexElement((sizeof(float) * 3) * 2, VertexElementFormat.Color, VertexElementUsage.Color, 0),
     new VertexElement((sizeof(float) * 3) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
     );

  public VertexPositionNormalColorTexture(Vector3 p)
  {
     Position = p;
     Normal = Vector3.Zero;
     Color = Color.White;
     TextureCoordinate = Vector2.Zero;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Color c)
  {
     Position = p;
     Normal = Vector3.Zero;
     Color = c;
     TextureCoordinate = Vector2.Zero;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Vector2 t)
  {
     Position = p;
     Normal = Vector3.Zero;
     Color = Color.White;
     TextureCoordinate = t;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Color c, Vector2 t)
  {
     Position = p;
     Normal = Vector3.Zero;
     Color = c;
     TextureCoordinate = t;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Color c)
  {
     Position = p;
     Normal = n;
     Color = c;
     TextureCoordinate = Vector2.Zero;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Vector2 t)
  {
     Position = p;
     Normal = n;
     Color = Color.White;
     TextureCoordinate = t;
  }

  public VertexPositionNormalColorTexture(Vector3 p, Vector3 n, Color c, Vector2 t)
  {
     Position = p;
     Normal = n;
     Color = c;
     TextureCoordinate = t;
  }
}
}

还有游戏类:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame2
{
  public class Game1 : Microsoft.Xna.Framework.Game
  {
  GraphicsDeviceManager graphics;
  SpriteBatch spriteBatch;
  ViewerManager viewer;

  List<VertexPositionNormalColorTexture> vertices;
  List<short> indices;
  Texture2D thumbnail;

  VertexBuffer vertexBuf;
  IndexBuffer indexBuf;

  RasterizerState rasterizerState;
  BasicEffect basicEffect;

  Matrix worldMatrix;
  Matrix viewMatrix;
  Matrix projectionMatrix;

  public Game1()
  {
     graphics = new GraphicsDeviceManager(this);
     Content.RootDirectory = "Content";
  }

  protected override void Initialize()
  {
     viewer = new ViewerManager(graphics, new Vector3(0.0f, 0.0f, 5.0f), new Vector3(0.0f, 0.0f, 0.0f), 500);

     vertices = new List<VertexPositionNormalColorTexture>() {

        new VertexPositionNormalColorTexture(new Vector3(-1, -1, 0), Color.Yellow, new Vector2(0, 1)),
        new VertexPositionNormalColorTexture(new Vector3(-1, 1, 0), Color.Yellow, new Vector2(0, 0)),
        new VertexPositionNormalColorTexture(new Vector3(1, 1, 0), Color.Yellow, new Vector2(1, 0)),

        new VertexPositionNormalColorTexture(new Vector3(-1, -1, 0), Color.Yellow, new Vector2(0, 1)),
        new VertexPositionNormalColorTexture(new Vector3(1, 1, 0), Color.Yellow, new Vector2(1, 0)),
        new VertexPositionNormalColorTexture(new Vector3(1, -1, 0), Color.Yellow, new Vector2(1, 1)),
     };
     indices = new List<short>() {
        0, 1, 2, 3, 4, 5
     };

     basicEffect = new BasicEffect(graphics.GraphicsDevice);

     worldMatrix = Matrix.CreateTranslation(0.0f, 0.0f, 0.0f) * Matrix.CreateScale(3);
     viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 5.0f), new Vector3(0.0f, 0.0f, 0.0f), Vector3.Up);
     projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(90), graphics.GraphicsDevice.Viewport.AspectRatio, 1f, 50f);

     vertexBuf = new VertexBuffer(graphics.GraphicsDevice, VertexPositionNormalColorTexture.VertexDeclaration, 500, BufferUsage.WriteOnly);
     indexBuf = new IndexBuffer(graphics.GraphicsDevice, IndexElementSize.SixteenBits, 500, BufferUsage.WriteOnly);

     rasterizerState = new RasterizerState();
     rasterizerState.CullMode = CullMode.None;

     base.Initialize();
  }

  protected override void LoadContent()
  {
     spriteBatch = new SpriteBatch(GraphicsDevice);
     thumbnail = this.Content.Load<Texture2D>("GameThumbnail");
  }

  protected override void UnloadContent()
  {
     this.Content.Unload();
  }

  protected override void Update(GameTime gameTime)
  {
     if (Keyboard.GetState().IsKeyDown(Keys.Escape))
        this.Exit();

     base.Update(gameTime);
  }

  protected override void Draw(GameTime gameTime)
  {
     GraphicsDevice.Clear(Color.CornflowerBlue);
     graphics.GraphicsDevice.RasterizerState = rasterizerState;

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

     basicEffect.VertexColorEnabled = true;
     basicEffect.TextureEnabled = true;
     basicEffect.Texture = thumbnail;

     vertexBuf.SetData<VertexPositionNormalColorTexture>(vertices.ToArray());
     indexBuf.SetData<short>(indices.ToArray());

     graphics.GraphicsDevice.SetVertexBuffer(vertexBuf);
     graphics.GraphicsDevice.Indices = indexBuf;

     foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
     {
        pass.Apply();

        graphics.GraphicsDevice.DrawUserIndexedPrimitives(
           PrimitiveType.TriangleList,
           vertices.ToArray(),
           0,
           vertices.Count,
           indices.ToArray(),
           0,
           2,
           VertexPositionNormalColorTexture.VertexDeclaration);
     }
     graphics.GraphicsDevice.Indices = null;
     graphics.GraphicsDevice.SetVertexBuffer(null);

     base.Draw(gameTime);
  }
 }
}

【问题讨论】:

    标签: c# xna-4.0


    【解决方案1】:

    我发现了问题。我为一个顶点分配了太多内存,这导致了奇怪的纹理。它在顶点声明的这一部分:

    new VertexElement((sizeof(float) * 3) * 2, VertexElementFormat.Color, VertexElementUsage.Color, 0),
     new VertexElement((sizeof(float) * 3) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
    

    Color 类型的大小实际上不是浮点/整数,而是字节。因此我不得不这样说:

    new VertexElement((sizeof(float) * 3) * 2 + 4, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0)
    

    【讨论】:

      猜你喜欢
      • 2014-11-25
      • 2018-07-09
      • 2021-11-13
      • 2020-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多