Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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;
                }
            }
        }
Ejemplo n.º 3
0
        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();
        }