| |
Chrisor Member
Anmeldedatum: 07.07.2012 Beiträge: 11
|
Verfasst am: 07.07.2012, 22:25 Titel: Model wird nicht angezeigt |
|
Hallo Leute,
ich habe heute das erste mal mit XNA in der Abteilung 3d gearbeitet und ein erstes Problem bei dem ich nicht mehr weiter weiss tritt auf.
Ich habe mich in Matrizen und ähnliches schon eingelesen und anhand meines "neuen Wissens" gleic einmal 2 Klassen gebaut: GameObject3D und Camera3D.
Bei meinem Model handelt es scih um den "Startwürfel" von Blender welchen ich ordnungsgemäss exportiert habe. Er wurde in einer Test-Anwendung nach Tutorial auf XNA-Wiki auch schon einmal angezeigt, kann somit nicht die Fehlerquelle sein.
Nach dem Schritt für Schritt debugging war für mich eigentlich klar dass ser würfel gezeichnet ist, ich vermute also dass mit der kamera/ der projektionsmatrix etwas nicht stimmt.
Damit ihr euch selbst ein Bild machen könnt poste ich hier mal die Klassen und ein Zip des Projektes.
die Game-Klasse:
| Code: | public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
KeyboardState KB;
float AspectRatio, nearPlane, FarPlane;
Matrix ProjectionMatrix;
Camera3D camera;
GameObject3D cube;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
AspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
nearPlane = 1;
FarPlane = 1000;
ProjectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, AspectRatio, nearPlane, FarPlane);
camera = new Camera3D(this, Vector3.Zero, Vector3.Up);
cube = new GameObject3D(this, Content.Load<Model>("untitled"), new Vector3(0, 0, 100), ProjectionMatrix, camera.CameraMatrix);
camera.viewTarget = cube.position;
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
KB = Keyboard.GetState();
if (KB.IsKeyDown(Keys.Up)) cube.position.X += 1;
if (KB.IsKeyDown(Keys.Down)) cube.position.X -= 1;
if (KB.IsKeyDown(Keys.Right)) cube.position.Z += 1;
if (KB.IsKeyDown(Keys.Left)) cube.position.Z -= 1;
camera.viewTarget = cube.position;
camera.Update();
cube.Update();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
cube.Draw();
base.Draw(gameTime);
}
} |
die Kamera:
| Code: | public class Camera3D
{
public Vector3 position, viewTarget = Vector3.Zero, cameraUpVector;
public Matrix CameraMatrix;
public Camera3D(Game game, Vector3 Position, Vector3 CameraUpVector)
{
position = Position;
cameraUpVector = CameraUpVector;
}
public void Update()
{
CameraMatrix = Matrix.CreateLookAt(position, viewTarget, cameraUpVector);
}
} |
das Game-Object:
| Code: | public class GameObject3D
{
Model model;
public float yawY, pitchX, rollZ;
public Vector3 position;
Matrix[] transforms;
public Matrix ModelMatrix;
Matrix projectionmatrix, cameramatrix;
float modelscale;
public GameObject3D(Game game, Model Model, Vector3 Position, Matrix ProjectionMatrix, Matrix CameraMatrix, float ModelScale = 1, float Yaw = 0, float Pitch = 0, float Roll = 0)
{
model = Model;
position = Position;
projectionmatrix = ProjectionMatrix;
cameramatrix = CameraMatrix;
yawY = Yaw;
pitchX = Pitch;
rollZ = Roll;
modelscale = ModelScale;
transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
}
public void Update()
{
ModelMatrix = Matrix.CreateScale(modelscale) * Matrix.CreateFromYawPitchRoll(yawY, pitchX, rollZ) * Matrix.CreateTranslation(position);
}
public void Draw()
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = projectionmatrix;
effect.View = cameramatrix;
effect.World = transforms[mesh.ParentBone.Index] * ModelMatrix;
}
mesh.Draw();
}
}
} |
Ps. das kann ein WINZIGER Leichtsinnsfehler sein da ich heute erst angefangen habe. (mit C# arbeite ich allerdings schon 4 Jahre und mit XNA in 2D 1 1/2)
Mfg Chris |
|
| Nach oben |
|

|
Kevin Member
Anmeldedatum: 24.10.2008 Beiträge: 882 Wohnort: Karlsruhe
|
Verfasst am: 07.07.2012, 23:16 Titel: Re: Model wird nicht angezeigt |
|
Hi Chrisor,
Zuerst mal willkommen auf xnamag und ich hab da so eine Vermutung wo der Fehler liegen könnte.
| Code: | | cube = new GameObject3D(this, Content.Load<Model>("untitled"), new Vector3(0, 0, 100), ProjectionMatrix, camera.CameraMatrix); |
Im Konstruktor übergibst du da die CameraMatrix, diese ist vom Typ Matrix, was ein Struct ist, daher wird es by value übergeben und nicht by reference (sofern du es nicht explit anders sagst). Es wird also kopiert, das Problem ist nun, dass diese View Matrix noch gar nicht erzeugt wurde, da sie erst in der Update Methode der Camera angelegt wird.
Übergebe also stattdessen die ganze Camera an den Konstruktor (da diese eine Klasse ist wird es per Referenz übergeben) und erreche über camera.CameraMatrix dann jedes Frame die View Matrix. Es gibt dafür aber natürlich mehrere Lösungsansätze.
Wichtig ist auf alle Fälle, dass du den Unterschied zwischen "Call by Value" und "Call by Reference" verstehst. Falls dir das noch nicht bekannt ist kannst du ja mal googeln
Wenn weitere Fragen bestehen einfach melden. _________________ Mein Youtube Kanal |
|
| Nach oben |
|

|
Chrisor Member
Anmeldedatum: 07.07.2012 Beiträge: 11
|
Verfasst am: 08.07.2012, 00:43 Titel: |
|
Ist mir garnicht klar gewesen dass das ein struct ist!
Ob ich da wohl je alleine drauf gekommen wäre?
Gute Idee! Werde das ausprobieren.
Danke dir Kevin |
|
| Nach oben |
|

|
Chrisor Member
Anmeldedatum: 07.07.2012 Beiträge: 11
|
Verfasst am: 08.07.2012, 19:20 Titel: |
|
Vielen Dank für deine schnelle problemlösende Antwort!!
und ich war schon am verzweifeln!
Warum ist ne Matrix auch n struct und keine class ?
MfG chris
Ps. wo kann man hier gleich thanks verteilen?? |
|
| Nach oben |
|

|
Kevin Member
Anmeldedatum: 24.10.2008 Beiträge: 882 Wohnort: Karlsruhe
|
Verfasst am: 08.07.2012, 19:52 Titel: |
|
Kein Problem
| Chrisor hat Folgendes geschrieben: |
Warum ist ne Matrix auch n struct und keine class ?
|
Warum sind floats und die anderen primitiven Datentypen als structs implementiert? Weil das den Umgang damit einfach viel einfacher und sicherer macht. Wenn man mal einen solchen Typ an eine Methode übergibt und diese damit gerechnet kann es natürlich mal dazu kommen, dass der Wert in der Rechnung verändert wird. Wäre es jetzt wirklich als Referenz implementiert, so könnte es jetzt sein, dass die Variable an anderer Stelle einen falschen Wert hat (nämlich den in der Methode während der Rechnung gesetzten).
Und gleiches gilt auch für Matrizen und andere mathematische Datentypen. Du wirst wohl in jedem anderen Framework/Engine in C# solche mathematischen Datentpyen stets als structs implementiert sehen.
Neben Matrizen sind übrigens auch Vektoren, Quaternions und Color als structs implementiert.
Wie ich schon angedeutet hatte lässt sich in C# aber auch ein "Pass by Reference" erzwingen. Dies geht mit dem ref Keyword, in der Dokumentation finden sich dazu weitere Informationen. Siehe hier.
Für gewöhnlich übergibt man in deinem Fall aber entweder eine Referenz auf die Kamera Klasse im Konstruktor oder direkt die View und Projection Matrix bei jedem Draw Aufruf (wobei ersteres die schnellere Variante ist, da bei Call-by-Value die Daten kopiert werden müssen und bei Call-by-Refernce nur ein Pointer übergeben wird).
P.S.: Gibts hier nicht, ein einfaches Danke reicht auch aus  _________________ Mein Youtube Kanal |
|
| Nach oben |
|

|
Chrisor Member
Anmeldedatum: 07.07.2012 Beiträge: 11
|
Verfasst am: 09.07.2012, 16:48 Titel: |
|
wenn ich so drüber nachdenke ist es natürlich sinvoll...
trotzdem vielen Dank!
#CLOSED |
|
| Nach oben |
|

|
|
|
|