Пример #1
0
        public void Draw(RenderTarget target, RenderStates states)
        {
            Okno window       = (Okno)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);

            Kamera sceneCamera = window.sceny.Peek().mainCamera;

            Position = sceneCamera.Position;
            Transformacja t = sceneCamera.InverseTransform * Transform;

            t.Translate(cameraCenter);
            vX = t * vX;
            vY = t * vY;
            vZ = t * vZ;
            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);
        }
        //rysowanie trojkatow skierowanych do mnie z cieniem i przycieciem
        public void RenderowanieSceny(Scena scene, RenderTarget target, RenderStates states)
        {
            uint width  = target.Size.X;
            uint height = target.Size.Y;

            Buffer = new float[width, height];
            Bitmap = new Color[width, height];

            Transformacja cameraInvMatrixAndWorld = scene.mainCamera.InverseTransform * scene.worldTransform;
            Transformacja matView = Transformacja.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.Daleko / (scene.mainCamera.Daleko - scene.mainCamera.Blisko);
            m[3, 2]    = (-scene.mainCamera.Daleko * scene.mainCamera.Blisko) / (scene.mainCamera.Daleko - scene.mainCamera.Blisko);
            m[2, 3]    = 1.0f;
            m[3, 3]    = 0.0f;
            Transformacja matProj = new Transformacja(m);

            Transformacja matProjAndView = matView * matProj;

            Queue <Tri> sceneTriangles = new Queue <Tri>();

            foreach (Rysowalne drawable in scene.drawables)
            {
                Mesh mesh = drawable.GetMesh();
                foreach (Tri tri in mesh)
                {
                    sceneTriangles.Enqueue(mesh.Transform * tri);
                }
            }
            int c = sceneTriangles.Count;

            for (int i = 0; i < c; i++)
            {
                Tri t = sceneTriangles.Dequeue();
                sceneTriangles.Enqueue(cameraInvMatrixAndWorld * t);
            }
            for (int i = 0; i < c; i++)
            {
                Tri        t   = sceneTriangles.Dequeue();
                List <Tri> clt = Clipowanie(new Vec3(0, 0, scene.mainCamera.Blisko), new Vec3(0, 0, 1), t);
                foreach (var clippedTriangle in clt)
                {
                    sceneTriangles.Enqueue(clippedTriangle);
                }
            }
            c = sceneTriangles.Count;
            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;
            for (int i = 0; i < c; i++)
            {
                Tri     t  = sceneTriangles.Dequeue();
                float[] Is = new float[3] {
                    0, 0, 0
                };
                Vec3  N  = t.NormalVector;
                float kd = t.KD;
                float ks = t.KS;
                float n  = t.N;
                foreach (ZrodloSwiatla lsrc in scene.Lampy)
                {
                    Vec3 lightPos = cameraInvMatrixAndWorld * lsrc.Position;
                    for (int j = 0; j < 3; j++)
                    {
                        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.Intensywnosc * (kd * N.Dot(L) + ks * minus * (float)Math.Pow(V.Dot(R), n));
                        Math.Max(I, 0);
                        Is[j] += I;
                    }
                }
                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);

                Wierzcholek vert0 = new Wierzcholek(t[0].Position, color0);
                Wierzcholek vert1 = new Wierzcholek(t[1].Position, color1);
                Wierzcholek vert2 = new Wierzcholek(t[2].Position, color2);
                sceneTriangles.Enqueue(new Tri(vert0, vert1, vert2, t.KS, t.KD, t.N));
            }
            for (int i = 0; i < c; i++)
            {
                Tri t = sceneTriangles.Dequeue();
                sceneTriangles.Enqueue(matProjAndView * t);
            }
            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 = Clipowanie(new Vec3(), new Vec3(0, 1, 0), t2);
                            break;

                        case 1:
                            clippedTriangles = Clipowanie(new Vec3(0, height - 1, 0), new Vec3(0, -1, 0), t2);
                            break;

                        case 2:
                            clippedTriangles = Clipowanie(new Vec3(), new Vec3(1, 0, 0), t2);
                            break;

                        case 3:
                            clippedTriangles = Clipowanie(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);
                }
            }
            while (sceneTriangles.Count > 0)
            {
                Tri t = sceneTriangles.Dequeue();
                RysujTrojkat(t, PrimitiveType.Triangles);
            }
            foreach (ZrodloSwiatla light in scene.Lampy)
            {
                Vec3 lpos = cameraInvMatrixAndWorld * light.Position;
                if (lpos.Z > 0)
                {
                    Vec3 lPosOnScreen = matProjAndView * lpos;
                    UstawPixel(lPosOnScreen, (Vec4)Color.White);
                    UstawPixel(lPosOnScreen + new Vec3(0, 1), (Vec4)Color.White);
                    UstawPixel(lPosOnScreen + new Vec3(1, 0), (Vec4)Color.White);
                    UstawPixel(lPosOnScreen + new Vec3(1, 1), (Vec4)Color.White);
                }
            }
            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();
        }