public void printPolyZ(RPolygon pIn)
        {
            if (pIn.isEpsilonGeometry())
            {
                return;
            }

            RPolygon polygon = pIn.reSort();

            if (polygon.isOffScreen(this.pixelLeftTop, this.pixelRightBottom))
            {
                return;
            }

            if (polygon.isFlatTop())
            {
                printPolyFlatTopZ(polygon);
            }
            else
            {
                if (polygon.isFlatBottom())
                {
                    printPolyFlatBottomZ(polygon);
                }
                else
                {
                    RPolygon p1 = polygon.getBottomFlat();
                    printPolyFlatBottomZ(p1);

                    RPolygon p2 = polygon.getTopFlat();
                    printPolyFlatTopZ(p2);
                }
            }
        }
Beispiel #2
0
        public void calculateProj(float nearPlane = 0.1f, float farPlane = 1000.0f)
        {
            polygons_proj = new List <RPolygon>();
            foreach (RPolygon poly in polygons_view)
            {
                Vec3f nearPlaneNormal = new Vec3f(0.0f, 0.0f, 1.0f);
                Vec3f nearPlaneP0     = new Vec3f(0.0f, 0.0f, nearPlane);

                float sideOfPoint1 = nearPlaneNormal.dot(poly.vertex0.position - nearPlaneP0);
                float sideOfPoint2 = nearPlaneNormal.dot(poly.vertex1.position - nearPlaneP0);
                float sideOfPoint3 = nearPlaneNormal.dot(poly.vertex2.position - nearPlaneP0);

                if (sideOfPoint1 <= 0 || sideOfPoint2 <= 0 || sideOfPoint3 <= 0)
                {
                    poly.visible = false;
                }

                if (poly.visible)
                {
                    RVertex vertex1 = new RVertex(poly.vertex0);
                    vertex1.position = new Vec3f(proj * poly.v0);

                    RVertex vertex2 = new RVertex(poly.vertex1);
                    vertex2.position = new Vec3f(proj * poly.v1);

                    RVertex vertex3 = new RVertex(poly.vertex2);
                    vertex3.position = new Vec3f(proj * poly.v2);

                    RPolygon newPolygon = new RPolygon(vertex1, vertex2, vertex3, poly.rasterType, poly.texture);
                    float    cosTheta   = newPolygon.normalCalc().dot(GlobalDirection.forward3f);
                    newPolygon.visible = cosTheta >= 0.0f ? false : true;

                    if (newPolygon.visible)
                    {
                        polygons_proj.Add(newPolygon);
                    }
                }
            }
        }
Beispiel #3
0
        public void calculateView(bool needToSort)
        {
            polygons_view = new List <RPolygon>();
            foreach (RPolygon poly in polygons_world)
            {
                RVertex vertex1 = new RVertex(poly.vertex[0]);
                vertex1.position = new Vec3f(view * poly.v0);

                RVertex vertex2 = new RVertex(poly.vertex[1]);
                vertex2.position = new Vec3f(view * poly.v1);

                RVertex vertex3 = new RVertex(poly.vertex[2]);
                vertex3.position = new Vec3f(view * poly.v2);

                RPolygon newPolygon = new RPolygon(vertex1, vertex2, vertex3, poly.rasterType, poly.texture);

                polygons_view.Add(newPolygon);
            }

            if (needToSort)
            {
                polygons_view = polygons_view.OrderBy(p => p.center).ToList();
            }
        }
Beispiel #4
0
        public void calculateProj()
        {
            polygons_proj = new List <RPolygon>();
            foreach (RPolygon poly in polygons_view)
            {
                RVertex vertex1 = new RVertex(poly.vertex[0]);
                vertex1.position = new Vec3f(proj * poly.v0);

                RVertex vertex2 = new RVertex(poly.vertex[1]);
                vertex2.position = new Vec3f(proj * poly.v1);

                RVertex vertex3 = new RVertex(poly.vertex[2]);
                vertex3.position = new Vec3f(proj * poly.v2);

                RPolygon newPolygon = new RPolygon(vertex1, vertex2, vertex3, poly.rasterType, poly.texture);
                float    cosTheta   = newPolygon.normalCalc().dot(GlobalDirection.forward3f);
                newPolygon.visible = cosTheta >= 0.0f ? false : true;

                if (newPolygon.visible)
                {
                    polygons_proj.Add(newPolygon);
                }
            }
        }
Beispiel #5
0
        public void calculateAll(float nearPlane, float farPlane, float width, float height, bool isNDC, bool backFaceCull = true)
        {
            polygons_raster = new List <RPolygon>();
            object sync = new object();

            Parallel.ForEach <RPolygon>(
                polygons,
                poly => {
                Mat4f mwv = model;
                mwv       = mwv * world;
                mwv       = mwv * view;

                RVertex vertex1  = new RVertex(poly.vertex0);
                vertex1.position = new Vec3f(mwv * poly.v0);

                RVertex vertex2  = new RVertex(poly.vertex1);
                vertex2.position = new Vec3f(mwv * poly.v1);

                RVertex vertex3  = new RVertex(poly.vertex2);
                vertex3.position = new Vec3f(mwv * poly.v2);

                Vec3f nearPlaneNormal = new Vec3f(0.0f, 0.0f, 1.0f);
                Vec3f nearPlaneP0     = new Vec3f(0.0f, 0.0f, nearPlane);

                Vec3f farPlaneNormal = new Vec3f(0.0f, 0.0f, -1.0f);
                Vec3f farPlaneP0     = new Vec3f(0.0f, 0.0f, farPlane);

                float sideOfPoint1near = nearPlaneNormal.dot(vertex1.position - nearPlaneP0);
                float sideOfPoint2near = nearPlaneNormal.dot(vertex2.position - nearPlaneP0);
                float sideOfPoint3near = nearPlaneNormal.dot(vertex3.position - nearPlaneP0);

                float sideOfPoint1far = farPlaneNormal.dot(vertex1.position - farPlaneP0);
                float sideOfPoint2far = farPlaneNormal.dot(vertex2.position - farPlaneP0);
                float sideOfPoint3far = farPlaneNormal.dot(vertex3.position - farPlaneP0);

                if ((sideOfPoint1near >= 0 && sideOfPoint2near >= 0 && sideOfPoint3near >= 0) && (sideOfPoint1far >= 0 && sideOfPoint2far >= 0 && sideOfPoint3far >= 0))
                {
                    vertex1.position = new Vec3f(proj * vertex1.position);
                    vertex2.position = new Vec3f(proj * vertex2.position);
                    vertex3.position = new Vec3f(proj * vertex3.position);

                    vertex1.position.x = isNDC ? (vertex1.position.x + 1.0f) * 0.5f * width : vertex1.position.x * width;
                    vertex1.position.y = isNDC ? (vertex1.position.y + 1.0f) * 0.5f * height : vertex1.position.y * height;

                    vertex2.position.x = isNDC ? (vertex2.position.x + 1.0f) * 0.5f * width : vertex2.position.x * width;
                    vertex2.position.y = isNDC ? (vertex2.position.y + 1.0f) * 0.5f * height : vertex2.position.y * height;

                    vertex3.position.x = isNDC ? (vertex3.position.x + 1.0f) * 0.5f * width : vertex3.position.x * width;
                    vertex3.position.y = isNDC ? (vertex3.position.y + 1.0f) * 0.5f * height : vertex3.position.y * height;

                    RPolygon newPolygon = new RPolygon(vertex1, vertex2, vertex3, poly.rasterType, poly.texture);

                    float cosTheta     = newPolygon.normalCalc().dot(GlobalDirection.forward3f);
                    newPolygon.visible = cosTheta >= 0.0f ? false : true;

                    if (!backFaceCull || newPolygon.visible)
                    {
                        newPolygon.sort();
                        lock (sync) {
                            polygons_raster.Add(newPolygon);
                        }
                    }
                }
            }
                );
        }
        public void printPolyFlatTopZ(RPolygon poly)
        {
            Vec3f v0 = new Vec3f(poly.v0);
            Vec3f v1 = new Vec3f(poly.v1);
            Vec3f v2 = new Vec3f(poly.v2);

            bool clockWise = v1.x > v0.x ? true : false;

            if (!clockWise)
            {
                Vec3f temp = v1;
                v1 = v0;
                v0 = temp;
            }

            float height = v2.y - v0.y;

            float dx_left  = (v2.x - v0.x) / height;
            float dx_right = (v2.x - v1.x) / height;

            float xStart = v0.x;
            float xEnd   = v1.x;

            int iy1;
            int iy3;
            int loop_y;

            if (v0.y < 0.0f)
            {
                xStart = xStart + dx_left * (-v0.y);
                xEnd   = xEnd + dx_right * (-v0.y);

                v0.y = 0.0f;
                iy1  = 0;
            }
            else
            {
                iy1 = (int)Math.Ceiling(v0.y);

                xStart = xStart + dx_left * ((float)iy1 - v0.y);
                xEnd   = xEnd + dx_right * ((float)iy1 - v0.y);
            }

            if (v2.y > pixelHeight)
            {
                v2.y = pixelHeight;
                iy3  = (int)v2.y - 1;
            }
            else
            {
                iy3 = (int)Math.Ceiling(v2.y) - 1;
            }

            float v0z   = 1.0f / v0.z;
            float v1z   = 1.0f / v1.z;
            float v2z   = 1.0f / v2.z;
            float yTemp = v0.y;

            if (v0.x >= 0 && v0.x < pixelWidth && v1.x >= 0 && v1.x < pixelWidth && v2.x >= 0 && v2.x < pixelWidth)
            {
                for (loop_y = iy1; loop_y <= iy3; loop_y++)
                {
                    int   ixStart = (int)xStart;
                    int   ixEnd   = (int)xEnd;
                    float xTemp   = xStart;

                    for (int x = ixStart; x < ixEnd; x++)
                    {
                        Vec2f p = new Vec2f(xTemp, loop_y);
                        Vec3f w = poly.nlambdas(p);
                        float z = 1.0f / (w.x * v0z + w.y * v1z + w.z * v2z);

                        Vec3f color = new Vec3f(
                            (poly.c0.r * v0z * w.x + poly.c1.r * v1z * w.y + poly.c2.r * v2z * w.z) * z,
                            (poly.c0.g * v0z * w.x + poly.c1.g * v1z * w.y + poly.c2.g * v2z * w.z) * z,
                            (poly.c0.b * v0z * w.x + poly.c1.b * v1z * w.y + poly.c2.b * v2z * w.z) * z
                            );

                        Vec2f UV = new Vec2f(
                            (poly.t0.x * v0z * w.x + poly.t1.x * v1z * w.y + poly.t2.x * v2z * w.z) * z,
                            (poly.t0.y * v0z * w.x + poly.t1.y * v1z * w.y + poly.t2.y * v2z * w.z) * z
                            );

                        bool alphaColor = false;
                        if (poly.rasterType == RPolygon.RasterType.Textured)
                        {
                            Vec4f texColor = poly.texture.sampleTextureA(UV);
                            if (texColor.a == 1.0f)
                            {
                                color.x = texColor.r;
                                color.y = texColor.g;
                                color.z = texColor.b;
                            }
                            else
                            {
                                alphaColor = true;
                            }
                        }

                        if (!alphaColor)
                        {
                            printPixelZ(
                                x,
                                loop_y,
                                z,
                                color
                                );
                        }

                        xTemp += 1.0f;
                    }

                    xStart += dx_left;
                    xEnd   += dx_right;
                    yTemp  += 1.0f;
                }
            }
            else
            {
                for (loop_y = iy1; loop_y <= iy3; loop_y++)
                {
                    float left  = xStart;
                    float right = xEnd;

                    xStart += dx_left;
                    xEnd   += dx_right;

                    if (left < 0)
                    {
                        left = 0;
                        if (right < 0)
                        {
                            continue;
                        }
                    }

                    if (right > pixelWidth)
                    {
                        right = pixelWidth;
                        if (left > pixelWidth)
                        {
                            continue;
                        }
                    }

                    int   ixStart = (int)left;
                    int   ixEnd   = (int)right;
                    float xTemp   = left;

                    for (int x = ixStart; x < ixEnd; x++)
                    {
                        Vec2f p = new Vec2f(xTemp, loop_y);
                        Vec3f w = poly.nlambdas(p);
                        float z = 1.0f / (w.x * v0z + w.y * v1z + w.z * v2z);

                        Vec3f color = new Vec3f(
                            (poly.c0.r * v0z * w.x + poly.c1.r * v1z * w.y + poly.c2.r * v2z * w.z) * z,
                            (poly.c0.g * v0z * w.x + poly.c1.g * v1z * w.y + poly.c2.g * v2z * w.z) * z,
                            (poly.c0.b * v0z * w.x + poly.c1.b * v1z * w.y + poly.c2.b * v2z * w.z) * z
                            );

                        Vec2f UV = new Vec2f(
                            (poly.t0.x * v0z * w.x + poly.t1.x * v1z * w.y + poly.t2.x * v2z * w.z) * z,
                            (poly.t0.y * v0z * w.x + poly.t1.y * v1z * w.y + poly.t2.y * v2z * w.z) * z
                            );

                        bool alphaColor = false;
                        if (poly.rasterType == RPolygon.RasterType.Textured)
                        {
                            Vec4f texColor = poly.texture.sampleTextureA(UV);
                            if (texColor.a == 1.0f)
                            {
                                color.x = texColor.r;
                                color.y = texColor.g;
                                color.z = texColor.b;
                            }
                            else
                            {
                                alphaColor = true;
                            }
                        }
                        if (!alphaColor)
                        {
                            printPixelZ(
                                x,
                                loop_y,
                                z,
                                color
                                );
                        }

                        xTemp += 1.0f;
                    }

                    yTemp += 1.0f;
                }
            }
        }
 public void printTriangleWireframe(RPolygon polygon, Vec3f color)
 {
     printLine(new Linef(polygon.v0, polygon.v1), color);
     printLine(new Linef(polygon.v1, polygon.v2), color);
     printLine(new Linef(polygon.v2, polygon.v0), color);
 }
Beispiel #8
0
        public void printPolyZ(RPolygon pIn)
        {
            RPolygon polygon     = pIn.reSort();
            float    area        = polygon.screenArea();
            float    oneOverArea = 1.0f / area;

            Vec3f v0 = polygon.v0;
            Vec3f v1 = polygon.v1;
            Vec3f v2 = polygon.v2;

            if (polygon.isEpsilonGeometry())
            {
                return;
            }

            if (polygon.isOffScreen(this.pixelLeftTop, this.pixelRightBottom))
            {
                return;
            }

            if (area < 1.0f && area > -1.0f)
            {
                return;
            }

            Vec2i leftTop     = polygon.topLeft();
            Vec2i bottomRight = polygon.bottomRight();

            if (leftTop.x < 0)
            {
                leftTop.x = 0;
            }

            if (leftTop.y < 0)
            {
                leftTop.y = 0;
            }

            if (bottomRight.x >= pixelWidth)
            {
                bottomRight.x = pixelWidth - 1;
            }

            if (bottomRight.y >= pixelHeight)
            {
                bottomRight.y = pixelHeight - 1;
            }

            for (int x = leftTop.x; x < bottomRight.x; x++)
            {
                for (int y = leftTop.y; y < bottomRight.y; y++)
                {
                    Vec2f p = new Vec2f(x, y);
                    Vec3f w = polygon.lambdas(p);

                    if ((w.x >= 0.0f && w.y >= 0.0f && w.z >= 0.0f) || (w.x <= 0.0f && w.y <= 0.0f && w.z <= 0.0f))
                    {
                        w *= oneOverArea;

                        float z  = 1.0f / (v0.z * w.x + v1.z * w.y + v2.z * w.z);
                        Vec2f UV = new Vec2f(
                            (polygon.vertex0.textureCoordinates.x * w.x + polygon.vertex1.textureCoordinates.x * w.y + polygon.vertex2.textureCoordinates.x * w.z) * z,
                            (polygon.vertex0.textureCoordinates.y * w.x + polygon.vertex1.textureCoordinates.y * w.y + polygon.vertex2.textureCoordinates.y * w.z) * z
                            );
                        Vec4f texColor = polygon.texture.sampleTextureA(UV);
                        printPixelZ(x, y, z, new Vec3f(texColor));
                    }
                }
            }
        }