我正在尝试在另一个班级中绘制模型。 我试图在另一个类中绘制模型。但是,我的模型根本无法使用我所做的代码进行渲染。
此处 Game1的代码:(注意:这些代码适用于Game1)
private Vector3 position = new Vector3(0, 0, 0);
private Matrix world;
private Matrix view;
private Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), 800f / 600f, 0.1f, 100f);
private Model car;
SpriteBatch spriteBatch;
GraphicsDeviceManager graphics;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
Vector3 transformedReference = Vector3.Transform(new Vector3(0, 5, 15), Matrix.CreateRotationY(0f));
view = Matrix.CreateLookAt(position + transformedReference, position, Vector3.Up);
}
protected override void Initialize()
{
Components.Add(new Car(this, view, projection));
world = Matrix.CreateTranslation(position);
Vector3 transformedReference = Vector3.Transform(new Vector3(0, 5, 15), Matrix.CreateRotationY(0f));
view = Matrix.CreateLookAt(position + transformedReference, position, Vector3.Up);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
car = Content.Load < Model > ("car\\car");
}
public void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach(ModelMesh mesh in model.Meshes)
{
foreach(BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.World = mesh.ParentBone.Transform * world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
world = Matrix.CreateTranslation(position);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
DrawModel(car, world, view, projection);
base.Draw(gameTime);
}
这里是另一个类的代码:(注意:这些代码效果不佳,或者模型无法在Game1图片上呈现)
public class Car: DrawableGameComponent
{
public Model CarModel
{
get;
set;
}
private Vector3 position = new Vector3(0, 0, 0);
private Matrix World = Matrix.CreateTranslation(new Vector3(0, 0, 0));
public Matrix Camera
{
get;
set;
}
public Matrix Projection
{
get;
set;
}
public Game1 GameParent
{
get;
set;
}
public Car(Game1 game, Matrix view, Matrix projection): base(game)
{
view = Camera;
Projection = projection;
Camera = view;
GameParent = game;
World = Matrix.CreateTranslation(position);
base.Initialize();
}
public static void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach(ModelMesh mesh in model.Meshes)
{
foreach(BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.World = mesh.ParentBone.Transform * world;
effect.View = view;
effect.Projection = projection;
}
mesh.Draw();
}
}
protected override void LoadContent()
{
CarModel = GameParent.Content.Load < Model > ("car\\car");
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
DrawModel(CarModel, World, Camera, Projection); //DOESN'T WORK WELL!!
base.Draw(gameTime);
}
}
好的,我的观点只是想在另一个类中绘制3D模型,
好吧,我该怎么做才能解决这个问题?我希望你不介意帮助我,你可以理解我的意思..
答案 0 :(得分:2)
很难看出代码有什么问题,因为它包含两个版本。清理一下。以下是一些提示:
根据我的经验,您不希望将DrawableGameComponent用于单个对象。坚持编写自己的类并将它们放入集合或类似的东西。通过这种方式,您无需处理XNA的巫术,即可启动更新并为您绘制。更好地控制自己。
您不希望您的CAR处理View和Projection-Matrices。把它们留在你的Game-class中(现在应该有一个相机类)并将它们传递给你的Car.Draw方法。我看到你在构造函数中传递它,但Matrixes是值类型,据我所知,所以代码的其他部分对视图的更改不会传播到你的汽车。
所以将Car.Draw更改为:
public void Draw(Matrix view, Matrix projection)
{
DrawModel(view, projection);
}
正如您可能从我的绘制更改中获得的,您还应该使DrawModel成为常规方法(删除静态),这样它就不必接收模型和世界。
你的车应该有一个四元数或类似的轮换。因此可以写出Car.World:
Matrix World = Matrix.Identity;
//In update:
World = Matrix.FromQuaternion(Rotation) * Matrix.CreateTranslation(Position);
让Car的构造函数将Model作为参数。这样你也可以抛弃“GameParent”和LoadContent-Method。
在你的游戏课程中:
抛弃静态DrawModel方法。 抛弃田野世界和汽车。他们现在属于汽车级。
为您的汽车创建一个字段(非属性的类级别变量):
Car MyCar = null;
在Game1.LoadContent中:
MyCar = new Car(Content.Load<Model>("car//car"));
在Game1.Update中:
MyCar.Update(gameTime);
在Game1.Draw中:
GraphicsDevice.Clear(Color.CornFlowerBlue);
MyCar.Draw(View, Projection);
编辑;
对于游戏引擎,您通常会有一些目前缺少的“部分”:
相机系统可以简单如下:
public interface ICamera
{
Vector3 Position { get; }
Matrix View { get; }
Matrix Projection { get; }
void Update(float deltaTime);
void Target(Vector3 targetPosition);
}
public class CameraService
{
public static ICamera ActiveCamera { get; private set; }
public static void ActivateCamera(ICamera camera)
{
if (ActiveCamera != null)
camera.Target(ActiveCamera.Target);
ActiveCamera = camera;
}
public static Update(float deltaTime)
{
if (ActiveCamera != null)
ActiveCamera.Update(deltaTime);
}
}
public class BasicCamera: ICamera
{
public Vector3 Position { get; protected set; }
public Matrix View { get; protected set; }
public Matrix Projection { get; protected set; }
public void Target(Vector3 targetPosition)
{
View = Matrix.CreateLookAt(Position, targetPosition, something something);
}
public BasicCamera(Vector3 position, Vector3 target)
{
//Set shit up
}
}