【发布时间】: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);
}
}
}
【问题讨论】: