Exemple #1
0
        public void DrawTriangle(ColorRGB color, VertexBuffer vbx, int triangleIndice)
        {
            vbx.Volume.Triangles[triangleIndice].TransformWorld(vbx);

            var surface = RendererContext.Surface;

            PainterUtils.SortTrianglePoints(vbx, surface, triangleIndice, out var v0, out var v1, out var v2);

            var p0 = v0.ScreenPoint; var p1 = v1.ScreenPoint; var p2 = v2.ScreenPoint;

            var yStart = (int)Math.Max(p0.Y, 0);
            var yEnd   = (int)Math.Min(p2.Y, surface.Height - 1);

            // Out if clipped
            if (yStart > yEnd)
            {
                return;
            }

            var yMiddle = MathUtils.Clamp((int)p1.Y, yStart, yEnd);

            // This has to move elsewhere
            var lightPos = new Vector3(0, 10, 10);

            // computing the cos of the angle between the light vector and the normal vector
            // it will return a value between 0 and 1 that will be used as the intensity of the color

            var nl0 = MathUtils.ComputeNDotL(v0.WorldPoint, v0.WorldNormal, lightPos);
            var nl1 = MathUtils.ComputeNDotL(v1.WorldPoint, v1.WorldNormal, lightPos);
            var nl2 = MathUtils.ComputeNDotL(v2.WorldPoint, v2.WorldNormal, lightPos);

            if (PainterUtils.Cross2D(p0, p1, p2) > 0)
            {
                // P0
                //   P1
                // P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p2, p0, p1, nl0, nl2, nl0, nl1);
                paintHalfTriangle((int)yMiddle, yEnd, color, p0, p2, p1, p2, nl0, nl2, nl1, nl2);
            }
            else
            {
                //   P0
                // P1
                //   P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p1, p0, p2, nl0, nl1, nl0, nl2);
                paintHalfTriangle((int)yMiddle, yEnd, color, p1, p2, p0, p2, nl1, nl2, nl0, nl2);
            }
        }
        void ProcessScanLine(float y, float sx, float ex, float sz, float ez, ColorRGB color)
        {
            var surface = RendererContext.Surface;

            var minX = Math.Max(sx, 0);
            var maxX = Math.Min(ex, surface.Width);

            var mx = 1 / (ex - sx);

            for (var x = minX; x < maxX; x++)
            {
                var gradient = (x - sx) * mx;

                var z = MathUtils.Lerp(sz, ez, gradient);

                surface.PutPixel((int)x, (int)y, (int)z, color);
            }
        }
        public void DrawTriangle(ColorRGB color, VertexBuffer vbx, int triangleIndice)
        {
            vbx.Volume.Triangles[triangleIndice].TransformWorld(vbx);

            var surface = RendererContext.Surface;

            PainterUtils.SortTrianglePoints(vbx, surface, triangleIndice, out var v0, out var v1, out var v2);

            var p0 = v0.ScreenPoint; var p1 = v1.ScreenPoint; var p2 = v2.ScreenPoint;

            var yStart = (int)Math.Max(p0.Y, 0);
            var yEnd   = (int)Math.Min(p2.Y, surface.Height - 1);

            // Out if clipped
            if (yStart > yEnd)
            {
                return;
            }

            var yMiddle = MathUtils.Clamp((int)p1.Y, yStart, yEnd);

            var lightPos     = new Vector3(0, 10, 10);
            var vertexNormal = (v0.WorldNormal + v1.WorldNormal + v2.WorldNormal) / 3;
            var vertexCenter = (v0.WorldPoint + v1.WorldPoint + v2.WorldPoint) / 3;

            color = MathUtils.ComputeNDotL(vertexCenter, vertexNormal, lightPos) * color;

            if (PainterUtils.Cross2D(p0, p1, p2) > 0)
            {
                // P0
                //   P1
                // P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p2, p0, p1);
                paintHalfTriangle((int)yMiddle, yEnd, color, p0, p2, p1, p2);
            }
            else
            {
                //   P0
                // P1
                //   P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p1, p0, p2);
                paintHalfTriangle((int)yMiddle, yEnd, color, p1, p2, p0, p2);
            }
        }
        public void PutPixel(int x, int y, int z, ColorRGB color)
        {
#if DEBUG
            if (x > Width - 1 || x < 0 || y > Height - 1 || y < 0)
            {
                throw new OverflowException($"PutPixel X={x}/{Width}: Y={y}/{Height}, Depth={z}");
            }
#endif
            var index = x + y * Width;
            if (z > zBuffer[index])
            {
                renderContext.Stats.BehindZPixelCount++;
                return;
            }

            renderContext.Stats.DrawnPixelCount++;

            zBuffer[index] = z;

            Screen[index] = color.Color;
        }
        void paintHalfTriangle(int yStart, int yEnd, ColorRGB color, Vector3 pa, Vector3 pb, Vector3 pc, Vector3 pd)
        {
            var mg1 = pa.Y == pb.Y ? 1f : 1 / (pb.Y - pa.Y);
            var mg2 = pd.Y == pc.Y ? 1f : 1 / (pd.Y - pc.Y);

            for (var y = yStart; y <= yEnd; y++)
            {
                var gradient1 = ((y - pa.Y) * mg1).Clamp();
                var gradient2 = ((y - pc.Y) * mg2).Clamp();

                var sx = MathUtils.Lerp(pa.X, pb.X, gradient1);
                var ex = MathUtils.Lerp(pc.X, pd.X, gradient2);

                if (sx >= ex)
                {
                    continue;
                }

                var sz = MathUtils.Lerp(pa.Z, pb.Z, gradient1);
                var ez = MathUtils.Lerp(pc.Z, pd.Z, gradient2);

                ProcessScanLine(y, sx, ex, sz, ez, color);
            }
        }
        public void DrawTriangle(ColorRGB color, VertexBuffer vbx, int triangleIndice)
        {
            var surface = RendererContext.Surface;

            PainterUtils.SortTrianglePoints(vbx, surface, triangleIndice, out var v0, out var v1, out var v2);

            var p0 = v0.ScreenPoint; var p1 = v1.ScreenPoint; var p2 = v2.ScreenPoint;

            var yStart = (int)Math.Max(p0.Y, 0);
            var yEnd   = (int)Math.Min(p2.Y, surface.Height - 1);

            // Out if clipped
            if (yStart > yEnd)
            {
                return;
            }

            var yMiddle = MathUtils.Clamp((int)p1.Y, yStart, yEnd);

            if (PainterUtils.Cross2D(p0, p1, p2) > 0)
            {
                // P0
                //   P1
                // P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p2, p0, p1);
                paintHalfTriangle((int)yMiddle, yEnd, color, p0, p2, p1, p2);
            }
            else
            {
                //   P0
                // P1
                //   P2
                paintHalfTriangle(yStart, (int)yMiddle - 1, color, p0, p1, p0, p2);
                paintHalfTriangle((int)yMiddle, yEnd, color, p1, p2, p0, p2);
            }
        }
Exemple #7
0
        static void drawLine(FrameBuffer surface, WireFramePainter wireFramePainter, Matrix4x4 world2Projection, Vector3 worldP0, Vector3 worldP1, ColorRGB color)
        {
            var projectionP0 = Vector4.Transform(worldP0, world2Projection);
            var projectionP1 = Vector4.Transform(worldP1, world2Projection);

            wireFramePainter.DrawLine(surface, color, projectionP0, projectionP1);
        }