public void Draw(RenderTarget target, RenderStates states) { MainWindow window = (MainWindow)target; Vec3 vX = new Vec3(-20, 0, 0); Vec3 vY = new Vec3(0, -20, 0); Vec3 vZ = new Vec3(0, 0, -20); Vec3 cameraCenter = new Vec3(target.Size.X / 2, target.Size.Y / 2, 0); Camera sceneCamera = window.scenes.Peek().mainCamera; Position = sceneCamera.Position; Transform t = sceneCamera.InverseTransform * Transform; t.Translate(cameraCenter); vX = t * vX; vY = t * vY; vZ = t * vZ; //vertices Vertex[] vs = new Vertex[] { new Vertex(new Vector2f(vX.X, vX.Y), Color.Red), new Vertex(new Vector2f(cameraCenter.X, cameraCenter.Y), Color.Red), new Vertex(new Vector2f(vY.X, vY.Y), Color.Green), new Vertex(new Vector2f(cameraCenter.X, cameraCenter.Y), Color.Green), new Vertex(new Vector2f(vZ.X, vZ.Y), Color.Blue), new Vertex(new Vector2f(cameraCenter.X, cameraCenter.Y), Color.Blue), }; target.Draw(vs, PrimitiveType.Lines); }
public override void Keys() { Transform t = Transform.Identity.Rotate(new Vec3(0, mainCamera.Rotation.Y, 0)); foreach (var key in pressedKeys) { switch (key) { //Moving case Keyboard.Key.W: mainCamera.Position += t * new Vec3(0, 0, Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds()); break; case Keyboard.Key.S: mainCamera.Position += t * new Vec3(0, 0, -Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds()); break; case Keyboard.Key.A: mainCamera.Position += t * new Vec3(Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds(), 0, 0); break; case Keyboard.Key.D: mainCamera.Position += t * new Vec3(-Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds(), 0, 0); break; case Keyboard.Key.LShift: mainCamera.Position += t * new Vec3(0, -Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds(), 0); break; case Keyboard.Key.Space: mainCamera.Position += t * new Vec3(0, Options.Instance.MovingSpeedPerSec * deltaTime.AsSeconds(), 0); break; //camera tilt case Keyboard.Key.Q: mainCamera.Rotation += new Vec3(0, 0, Options.Instance.RotatingSpeedPerSec * deltaTime.AsSeconds()); break; case Keyboard.Key.E: mainCamera.Rotation -= new Vec3(0, 0, Options.Instance.RotatingSpeedPerSec * deltaTime.AsSeconds()); break; } } }
public void RenderScene(Scene scene, RenderTarget target, RenderStates states) { //1.matworld * transform mesha razy trojkat //2.przytniecie trojkatow kamerą(cos prawie jak culling frustrum ale o kacie 180 stopni) //3.wybrac tylko te ktore sa skierowane twarza do kamery //4.oswietlic wierzcholki trojkatow //5.projekcja na kamere(matIntoView* matProj *trojkat) //6.clip2D(czyli przyciac te ktore sa poza obrazem) //7.narysowac trojkaty //8.narysowac lightsource //9.narysowac texture na target uint width = target.Size.X; uint height = target.Size.Y; //init frame ZBuffer = new float[width, height]; Bitmap = new Color[width, height]; Transform cameraInvMatrixAndWorld = scene.mainCamera.InverseTransform * scene.worldTransform; Transform matView = Transform.Identity.Translate(new Vec3(1, 1, 0)).Scale(new Vec3(width / 2, height / 2, 1)); float fAspectRatio = height / (float)width; float fFovRad = 1.0f / (float)Math.Tan(scene.mainCamera.Fov * 0.5f / 180.0f * Math.PI); float[,] m = new float[4, 4]; m[0, 0] = fAspectRatio * fFovRad; m[1, 1] = fFovRad; m[2, 2] = scene.mainCamera.Far / (scene.mainCamera.Far - scene.mainCamera.Near); m[3, 2] = (-scene.mainCamera.Far * scene.mainCamera.Near) / (scene.mainCamera.Far - scene.mainCamera.Near); m[2, 3] = 1.0f; m[3, 3] = 0.0f; Transform matProj = new Transform(m); Transform matProjAndView = matView * matProj; Queue <Tri> sceneTriangles = new Queue <Tri>(); // collect all triangles foreach (Drawable3D drawable in scene.drawables) { Mesh mesh = drawable.GetMesh(); // TODO: this should return already transformed mesh foreach (Tri tri in mesh) { sceneTriangles.Enqueue(mesh.Transform * tri); } } //1. int c = sceneTriangles.Count; for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); sceneTriangles.Enqueue(cameraInvMatrixAndWorld * t); } //2. for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); List <Tri> clt = ClipAgainstPlane(new Vec3(0, 0, scene.mainCamera.Near), new Vec3(0, 0, 1), t); foreach (var clippedTriangle in clt) { sceneTriangles.Enqueue(clippedTriangle); } } c = sceneTriangles.Count; //3. for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); if (t.NormalVector.Dot(t[0].Position) < 0) { sceneTriangles.Enqueue(t); } } c = sceneTriangles.Count; //4. for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); float[] Is = new float[3] { 0, 0, 0 }; // ILLUMINATION - Phong Vec3 N = t.NormalVector; float kd = t.kd; float ks = t.ks; float n = t.n; foreach (LightSource lsrc in scene.lightSources) { Vec3 lightPos = cameraInvMatrixAndWorld * lsrc.Position; for (int j = 0; j < 3; j++) { //camera position (0,0,0) - vertex position (after camerainverese) Vec3 V = (-t[j].Position).Normal(); Vec3 L = (lightPos - t[j].Position).Normal(); Vec3 R = (-L - 2 * N.Dot(-L) * N).Normal(); float minus = (V.Dot(R) < 0) ? -1 : 1; float I = lsrc.Intensity * (kd * N.Dot(L) + ks * minus * (float)Math.Pow(V.Dot(R), n)); Math.Max(I, 0); Is[j] += I; } } //ambient light 0.2 for (int j = 0; j < 3; j++) { Is[j] = Math.Max(Is[j], 0.2f); } Vec4 color0 = new Vec4(t[0].Color.R * Is[0], t[0].Color.G * Is[0], t[0].Color.B * Is[0], t[0].Color.A); Vec4 color1 = new Vec4(t[1].Color.R * Is[1], t[1].Color.G * Is[1], t[1].Color.B * Is[1], t[1].Color.A); Vec4 color2 = new Vec4(t[2].Color.R * Is[2], t[2].Color.G * Is[2], t[2].Color.B * Is[2], t[2].Color.A); Vertex3 vert0 = new Vertex3(t[0].Position, color0); Vertex3 vert1 = new Vertex3(t[1].Position, color1); Vertex3 vert2 = new Vertex3(t[2].Position, color2); sceneTriangles.Enqueue(new Tri(vert0, vert1, vert2, t.ks, t.kd, t.n)); } //5. for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); sceneTriangles.Enqueue(matProjAndView * t); } //6. for (int i = 0; i < c; i++) { Tri t = sceneTriangles.Dequeue(); Queue <Tri> qTris = new Queue <Tri>(); qTris.Enqueue(t); int nNewTriangles = 1; for (int p = 0; p < 4; p++) { while (nNewTriangles > 0) { Tri t2 = qTris.Dequeue(); nNewTriangles--; List <Tri> clippedTriangles = new List <Tri>(); switch (p) { case 0: clippedTriangles = ClipAgainstPlane(new Vec3(), new Vec3(0, 1, 0), t2); break; case 1: clippedTriangles = ClipAgainstPlane(new Vec3(0, height - 1, 0), new Vec3(0, -1, 0), t2); break; case 2: clippedTriangles = ClipAgainstPlane(new Vec3(), new Vec3(1, 0, 0), t2); break; case 3: clippedTriangles = ClipAgainstPlane(new Vec3(width - 1, 0, 0), new Vec3(-1, 0, 0), t2); break; } foreach (var item in clippedTriangles) { qTris.Enqueue(item); } } nNewTriangles = qTris.Count; } foreach (var item in qTris) { sceneTriangles.Enqueue(item); } } //7. while (sceneTriangles.Count > 0) { Tri t = sceneTriangles.Dequeue(); if (Options.Instance.ShowWireframe) { //test zbuffer wireframe DrawTriangle(t, PrimitiveType.LineStrip); } else { //test zbuffer fill DrawTriangle(t, PrimitiveType.Triangles); } } //8. foreach (LightSource light in scene.lightSources) { Vec3 lpos = cameraInvMatrixAndWorld * light.Position; if (lpos.Z > 0) { Vec3 lPosOnScreen = matProjAndView * lpos; DrawPixel(lPosOnScreen, (Vec4)Color.White); DrawPixel(lPosOnScreen + new Vec3(0, 1), (Vec4)Color.White); DrawPixel(lPosOnScreen + new Vec3(1, 0), (Vec4)Color.White); DrawPixel(lPosOnScreen + new Vec3(1, 1), (Vec4)Color.White); } } //9. Image img = new Image(Bitmap); Texture texture = new Texture(img); Sprite s = new Sprite(texture); target.Draw(s, states); s.Dispose(); texture.Dispose(); img.Dispose(); }