Example #1
0
        public VAO(Mesh mesh)
        {
            var triangles = mesh.triangles;
            var vertices  = mesh.vertices;
            var normals   = mesh.normals;
            var uvs       = mesh.uv;

            vbo = new VertexIn[triangles.Length];

            Color color = Color.white;

            for (int i = 0; i < triangles.Length / 3; ++i)
            {
                for (int j = 0; j < 3; ++j)
                {
                    var v = new VertexIn();

                    var idx = triangles[i * 3 + j];

                    v.pos    = vertices[idx];
                    v.normal = normals[idx];
                    v.uv     = uvs[idx];
                    v.color  = color;

                    vbo[i * 3 + j] = v;
                }
            }
        }
        FragmentIn VS(VertexIn input)
        {
            FragmentIn output;
            Vector2    scaledInput = (input.Position * SizePos.Size) + SizePos.Position;

            output.Position = Mul(Projection, new Vector4(scaledInput, 0, 1));
            output.TexCoord = input.TexCoord;
            return(output);
        }
Example #3
0
        public VAO(ref Vector3[] vertices, ref Color[] colors)
        {
            vbo = new VertexIn[vertices.Length];

            for (int i = 0; i < vertices.Length; ++i)
            {
                var v = new VertexIn();
                v.pos   = vertices[i];
                v.color = colors[i];

                vbo[i] = v;
            }
        }
Example #4
0
        public void Execute(int i)
        {
            VertexIn inVal = input[triangles[i]];

            VertexOut outVal;

            outVal.position = math.mul(model, inVal.position);
            outVal.position = math.mul(view, outVal.position);
            outVal.position = math.mul(proj, outVal.position);

            outVal.texcoord0 = inVal.texcoord0;
            outVal.normal    = math.mul(model, inVal.normal);

            output[i] = outVal;
        }
Example #5
0
    public FragmentIn Vert(VertexIn v)
    {
        var vert = new FragmentIn();

        vert.worldPos = ShaderGlobal.l2wMat.MultiplyPoint3x4(v.pos);
        vert.normal   = ShaderGlobal.l2wInvTMat.MultiplyVector(v.normal).normalized;
        vert.uv       = v.uv;
        vert.color    = v.color;

        Vector4 pos = v.pos;

        pos.w       = 1;
        vert.vertex = ShaderGlobal.MVPMat * pos;

        return(vert);
    }
    public void DrawTriangle2D(VertexIn v1, VertexIn v2, VertexIn v3, Color color)
    {
        var p1 = v1.pos;
        var p2 = v2.pos;
        var p3 = v3.pos;

        // 保证v1,v2,v3 y轴依次变小
        if (p1.y < p2.y)
        {
            Swap(ref v1, ref v2);
        }
        if (p1.y < p3.y)
        {
            Swap(ref v1, ref v3);
        }
        if (p2.y < p3.y)
        {
            Swap(ref v2, ref v3);
        }

        p1 = v1.pos;
        p2 = v2.pos;
        p3 = v3.pos;

        if (p2.y == p3.y)
        {
            fillBottomFlatTriangle(v2, v3, v1, color);
        }
        else if (p1.y == p2.y)
        {
            fillBottomFlatTriangle(v1, v2, v3, color);
        }
        else
        {
            // y = y0 + k(x-x0)
            // x = x0 + 1/k*(y-y0)
            float k      = (p1.y - p3.y) / (p1.x - p3.x);
            float splitx = p3.x + (p2.y - p3.y) / k;
            float splity = p3.y + (splitx - p3.x) * k;

            var splitv = new VertexIn(splitx, splity);
            fillBottomFlatTriangle(v2, splitv, v1, color);
            fillBottomFlatTriangle(v2, splitv, v3, color);
        }
    }
    //   /\3
    // 1----2
    void fillBottomFlatTriangle(VertexIn v1, VertexIn v2, VertexIn v3, Color color)
    {
        var p1 = v1.pos;
        var p2 = v2.pos;
        var p3 = v3.pos;

        float slop1 = (p3.y - p1.y) / (p3.x - p1.x);
        float slop2 = (p3.y - p2.y) / (p3.x - p2.x);

        float curx1 = p1.x;
        float curx2 = p2.x;
        int   inc   = p1.y > p3.y ? -1 : 1;

        int scanline = (int)p1.y;
        int scanto   = (int)p3.y;

        if (scanline == scanto)
        {
            //三角形退化
            var start = new VertexIn(curx1, scanline);
            var end   = new VertexIn(curx2, scanline);
            DrawLine(start, end, ref color);
        }
        else
        {
            for (; scanline != scanto; scanline += inc)
            {
                var start = new VertexIn(curx1, scanline);
                var end   = new VertexIn(curx2, scanline);
                DrawLine(start, end, ref color);

                curx1 += inc / slop1;
                curx2 += inc / slop2;
            }
        }
    }
    public void DrawLine(VertexIn start, VertexIn end, ref Color color)
    {
        //裁剪不可见的线
        if (!CohenSutherlandLineClip(ref start.pos, ref end.pos, ClipLowLeft, ClipUpRight))
        {
            return;
        }

        int x0 = (int)start.pos.x;
        int x1 = (int)end.pos.x;

        int y0 = (int)start.pos.y;
        int y1 = (int)end.pos.y;

        if (x0 == x1 && y0 == y1)
        {
            //点
            DrawPixel(x0, y0, ref color);
        }
        else if (x0 == x1)
        {
            // 竖线
            int inc = y0 > y1 ? -1 : 1;
            for (var y = y0; y != y1; y += inc)
            {
                DrawPixel(x0, y, ref color);
            }
            DrawPixel(x1, y1, ref color);
        }
        else if (y0 == y1)
        {
            // 横线
            int inc = x0 > x1 ? -1 : 1;
            for (var x = x0; x != x1; x += inc)
            {
                DrawPixel(x, y0, ref color);
            }
            DrawPixel(x1, y1, ref color);
        }
        else
        {
            int dx = (x0 < x1) ? x1 - x0 : x0 - x1;
            int dy = (y0 < y1) ? y1 - y0 : y0 - y1;

            // k < 0
            if (dx > dy)
            {
                if (x1 < x0)
                {
                    Swap(ref x0, ref x1);
                    Swap(ref y0, ref y1);
                }

                int rem = 0, x, y;
                for (x = x0, y = y0; x <= x1; x++)
                {
                    DrawPixel(x, y, ref color);
                    rem += dy;
                    if (rem >= dx)
                    {
                        rem -= dx;
                        y   += (y1 > y0) ? 1 : -1;
                    }
                }
            }
            else
            {
                if (y1 < y0)
                {
                    Swap(ref x0, ref x1);
                    Swap(ref y0, ref y1);
                }
                int rem = 0, x, y;
                for (x = x0, y = y0; y <= y1; y++)
                {
                    DrawPixel(x, y, ref color);
                    rem += dx;
                    if (rem >= dy)
                    {
                        rem -= dy;
                        x   += (x1 > x0) ? 1 : -1;
                    }
                }
            }
        }
    }
        public static Primitive CreateSphere(GraphicsDevice device)
        {
            Primitive p            = new Primitive();
            float     diameter     = 1.0f;
            int       tessellation = 16;

            int verticalSegments   = tessellation;
            int horizontalSegments = tessellation * 2;

            var vertices = new VertexIn[(verticalSegments + 1) * (horizontalSegments + 1)];
            var indices  = new int[(verticalSegments) * (horizontalSegments + 1) * 6];

            float radius = diameter / 2;

            int vertexCount = 0;

            // Create rings of vertices at progressively higher latitudes.
            for (int i = 0; i <= verticalSegments; i++)
            {
                float v = 1.0f - (float)i / verticalSegments;

                var latitude = (float)((i * Math.PI / verticalSegments) - Math.PI / 2.0);
                var dy       = (float)Math.Sin(latitude);
                var dxz      = (float)Math.Cos(latitude);

                // Create a single ring of vertices at this latitude.
                for (int j = 0; j <= horizontalSegments; j++)
                {
                    float u = (float)j / horizontalSegments;

                    var longitude = (float)(j * 2.0 * Math.PI / horizontalSegments);
                    var dx        = (float)Math.Sin(longitude);
                    var dz        = (float)Math.Cos(longitude);

                    dx *= dxz;
                    dz *= dxz;

                    var normal            = new Vector3(dx, dy, dz);
                    var textureCoordinate = new Vector2(u, v);

                    vertices[vertexCount++] = new VertexIn()
                    {
                        Position = normal * radius, Normal = normal
                    };
                }
            }

            // Fill the index buffer with triangles joining each pair of latitude rings.
            int stride = horizontalSegments + 1;

            int indexCount = 0;

            for (int i = 0; i < verticalSegments; i++)
            {
                for (int j = 0; j <= horizontalSegments; j++)
                {
                    int nextI = i + 1;
                    int nextJ = (j + 1) % stride;

                    indices[indexCount++] = (i * stride + j);
                    indices[indexCount++] = (nextI * stride + j);
                    indices[indexCount++] = (i * stride + nextJ);

                    indices[indexCount++] = (i * stride + nextJ);
                    indices[indexCount++] = (nextI * stride + j);
                    indices[indexCount++] = (nextI * stride + nextJ);
                }
            }

            for (int i = 0; i < indices.Length; i += 3)
            {
                Utilities.Swap(ref indices[i], ref indices[i + 2]);
            }

            p.IndexBuffer  = SharpDX.Toolkit.Graphics.Buffer.Index.New(device, indices);
            p.VertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(device, vertices);

            return(p);
        }
        public static Primitive CreateCube(GraphicsDevice device)
        {
            Primitive p    = new Primitive();
            float     size = 1.0f;

            var vertices = new VertexIn[CubeFaceCount * 4];
            var indices  = new int[CubeFaceCount * 6];

            size /= 2.0f;

            int vertexCount = 0;
            int indexCount  = 0;

            // Create each face in turn.
            for (int i = 0; i < CubeFaceCount; i++)
            {
                Vector3 normal = faceNormals[i];

                // Get two vectors perpendicular both to the face normal and to each other.
                Vector3 basis = (i >= 4) ? Vector3.UnitZ : Vector3.UnitY;

                Vector3 side1;
                Vector3.Cross(ref normal, ref basis, out side1);

                Vector3 side2;
                Vector3.Cross(ref normal, ref side1, out side2);

                // Six indices (two triangles) per face.
                int vbase = i * 4;
                indices[indexCount++] = (vbase + 0);
                indices[indexCount++] = (vbase + 1);
                indices[indexCount++] = (vbase + 2);

                indices[indexCount++] = (vbase + 0);
                indices[indexCount++] = (vbase + 2);
                indices[indexCount++] = (vbase + 3);

                // Four vertices per face.
                vertices[vertexCount++] = new VertexIn()
                {
                    Position = (normal - side1 - side2) * size, Normal = normal
                };
                vertices[vertexCount++] = new VertexIn()
                {
                    Position = (normal - side1 + side2) * size, Normal = normal
                };
                vertices[vertexCount++] = new VertexIn()
                {
                    Position = (normal + side1 + side2) * size, Normal = normal
                };
                vertices[vertexCount++] = new VertexIn()
                {
                    Position = (normal + side1 - side2) * size, Normal = normal
                };
            }

            for (int i = 0; i < indices.Length; i += 3)
            {
                Utilities.Swap(ref indices[i], ref indices[i + 2]);
            }

            p.IndexBuffer  = SharpDX.Toolkit.Graphics.Buffer.Index.New(device, indices);
            p.VertexBuffer = SharpDX.Toolkit.Graphics.Buffer.Vertex.New(device, vertices);

            return(p);
        }