i learn xna , trying create room using vertices. went , try out riemeres xna tutorial , learn alot can't seem make camera work well, every time move left or right of image or textured seems disappear , reappear. please help.
here code.
public struct myownvertexformat { public vector3 position; private vector2 texcoord; public myownvertexformat(vector3 position, vector2 texcoord) { this.position = position; this.texcoord = texcoord; } public readonly static vertexdeclaration vertexdeclaration = new vertexdeclaration ( new vertexelement(0, vertexelementformat.vector3, vertexelementusage.position, 0), new vertexelement(sizeof(float) * 3, vertexelementformat.vector2, vertexelementusage.texturecoordinate, 0) ); } public class game1 : microsoft.xna.framework.game { graphicsdevicemanager graphics; graphicsdevice device; effect effect; matrix viewmatrix; matrix projectionmatrix; vertexbuffer vertexbuffer; vector3 camerapos; texture2d streettexture; private vector3 position = vector3.one; private float zoom = 2500; private float rotationy = 0.0f; private float rotationx = 0.0f; private matrix gameworldrotation; public game1() { graphics = new graphicsdevicemanager(this); content.rootdirectory = "content"; } protected override void initialize() { graphics.preferredbackbufferwidth =1024; graphics.preferredbackbufferheight = 768; graphics.isfullscreen = false; graphics.applychanges(); base.initialize(); } protected override void loadcontent() { device = graphicsdevice; effect = content.load<effect>("ourhlslfile"); setupvertices(); setupcamera(); streettexture = content.load<texture2d>("streettexture"); } private void updatekeyboard() { if (keyboard.getstate().iskeydown(keys.escape)) exit(); if (keyboard.getstate().iskeydown(keys.up)) rotationx += 1.0f; if (keyboard.getstate().iskeydown(keys.down)) rotationx -= 1.0f; if (keyboard.getstate().iskeydown(keys.left)) rotationy += 1.0f; if (keyboard.getstate().iskeydown(keys.right)) rotationy -= 1.0f; gameworldrotation = matrix.createrotationx(mathhelper.toradians(rotationx)) * matrix.createrotationy(mathhelper.toradians(rotationy)); } private void setupvertices() { myownvertexformat[] vertices = new myownvertexformat[12]; vertices[0] = new myownvertexformat(new vector3(-20, 0, 10), new vector2(-0.25f, 25.0f)); vertices[1] = new myownvertexformat(new vector3(-20, 0, -100), new vector2(-0.25f, 0.0f)); vertices[2] = new myownvertexformat(new vector3(2, 0, 10), new vector2(0.25f, 25.0f)); vertices[3] = new myownvertexformat(new vector3(2, 0, -100), new vector2(0.25f, 0.0f)); vertices[4] = new myownvertexformat(new vector3(2, 1, 10), new vector2(0.375f, 25.0f)); vertices[5] = new myownvertexformat(new vector3(2, 1, -100), new vector2(0.375f, 0.0f)); vertices[6] = new myownvertexformat(new vector3(3, 1, 10), new vector2(0.5f, 25.0f)); vertices[7] = new myownvertexformat(new vector3(3, 1, -100), new vector2(0.5f, 0.0f)); vertices[8] = new myownvertexformat(new vector3(-13, 1, 10), new vector2(0.75f, 25.0f)); vertices[9] = new myownvertexformat(new vector3(-13, 1, -100), new vector2(0.75f, 0.0f)); vertices[10] = new myownvertexformat(new vector3(-13, 21, 10), new vector2(1.25f, 25.0f)); vertices[11] = new myownvertexformat(new vector3(-13, 21, -100), new vector2(1.25f, 0.0f)); vertexbuffer = new vertexbuffer(device, myownvertexformat.vertexdeclaration, vertices.length, bufferusage.writeonly); vertexbuffer.setdata(vertices); } private void setupcamera() { camerapos = new vector3(-25, 13, 75); viewmatrix = matrix.createlookat(camerapos, new vector3(0, 2, -12), new vector3(0, 1, 0)); projectionmatrix = matrix.createperspectivefieldofview(mathhelper.piover4, device.viewport.aspectratio, 1.0f, 5000.0f); } protected override void unloadcontent() { } protected override void update(gametime gametime) { if (gamepad.getstate(playerindex.one).buttons.back == buttonstate.pressed) this.exit(); updatekeyboard(); base.update(gametime); } protected override void draw(gametime gametime) { device.clear(clearoptions.target | clearoptions.depthbuffer, color.darkslateblue, 1.0f, 0); effect.currenttechnique = effect.techniques["simplest"]; effect.parameters["xviewprojection"].setvalue(viewmatrix * projectionmatrix * gameworldrotation); effect.parameters["xtexture"].setvalue(streettexture); foreach (effectpass pass in effect.currenttechnique.passes) { pass.apply(); device.setvertexbuffer(vertexbuffer); device.drawprimitives(primitivetype.trianglestrip, 0, 10); } base.draw(gametime); } }
i assume it's projection issue. line, taken code, strengthens assumption:
viewmatrix * projectionmatrix * gameworldrotation tl;dr, correct order is:
gameworldrotation * viewmatrix * projectionmatrix please remember order matters when multiplying matrices. in mathematical terms:
matrix multiplication not commutative!
those 3 matrices map vector 3 different coordinate systems, world, view , projection space. vertices defined in object space. multiplying vector world (view, projection) matrix brings vector world (view, projection) space:
object space => world space => view space => projection space xna uses row vector layout (as opposed column vectors). means vector declared horizontally (x, y, z). skipping dry interesting details, means when transforming vector (multiplying vector matrix), vector left operand, while matrix right operand:
a := [3x3 matrix] (x, y, z) * = (x', y', z') // result 3d vector now in order apply 3 matrices use result of previous transformation input next transform:
w .... world matrix v .... view matrix w .... projection matrix x .... vector x' ... transformed vector x' = ((x * w) * v) * p finally, matrix multiplication associative (braces don't matter). , that's why can combine world, view , projection matrix single matrix before sending device:
x' = ((x * w) * v) * p = x * w * v * p = x * (w * v * p) world * view * projection. that's need. (and maybe basic matrix math future work.)
Comments
Post a Comment