public PhongShading(Bgr24Bitmap bitmap, Model model, ILighting lighting, bool d, bool n, bool s)
     : base(bitmap, model, lighting)
 {
     _d = d;
     _n = n;
     _s = s;
     _texturesEnabled = d || n || s;
 }
        private Vector3 GetDiffusedTextureVector(Bgr24Bitmap texture, float x, float y, Vector3 normal)
        {
            if (texture == null)
            {
                return(new Vector3(0));
            }
            var textureVector = Interpolate(texture, x, y);

            return(Vector3.Normalize(DiffuseColor) * Math.Max(Vector3.Dot(normal, Vector), 0) * textureVector);
        }
        private Vector3 GetAmbientTextureVector(Bgr24Bitmap texture, float x, float y)
        {
            if (texture == null)
            {
                return(new Vector3(0));
            }
            var textureVector = Interpolate(texture, x, y);

            return(Vector3.Normalize(AmbientColor) * textureVector);
        }
        private Vector3 GetSpecularTextureVector(Bgr24Bitmap texture, float x, float y, Vector3 normal)
        {
            if (texture == null)
            {
                return(new Vector3(0));
            }
            var reflectionVector = Vector3.Normalize(Vector3.Reflect(Vector, normal));
            var textureVector    = Interpolate(texture, x, y);

            // 𝑅 = 𝐿 − 2 ∙ (𝐿 ∙ 𝑁) ∙ 𝑁
            return(Vector3.Normalize(SpecularColor) * (float)Math.Pow(Math.Max(Vector3.Dot(reflectionVector, new Vector3(0, 0, -1)), 0), GlossCoefficient) * textureVector);
        }
        // Bilinear interpolation
        // z = (A(1 - x) + Bx)(1 - y) + (C(1 - x) + Dx)y
        // x = deltaX
        // y = deltaY
        private Vector3 Interpolate(Bgr24Bitmap texture, float x, float y)
        {
            int x1 = (int)x;
            int y1 = (int)y;

            float deltaX = x - x1;
            float deltaY = y - y1;

            var y0 = (1 - deltaX) * texture.GetVector(x1, y1) + deltaX * texture.GetVector(x1 + 1, y1);
            var y2 = (1 - deltaX) * texture.GetVector(x1, y1 + 1) + deltaX * texture.GetVector(x1 + 1, y1 + 1);

            return((1 - deltaX) * y0 + deltaX * y2);
        }
        private Vector3?GetNormalTextureVector(Bgr24Bitmap texture, float x, float y, Matrix4x4 modelMatrix)
        {
            if (texture == null)
            {
                return(null);
            }
            var normal = Interpolate(texture, x, y);

            //  𝑁 = Ct * 2 - 1
            normal -= new Vector3(byte.MaxValue) / 2;
            normal  = Vector3.Normalize(normal);

            return(Vector3.Normalize(Vector3.TransformNormal(normal, modelMatrix)));
        }
Пример #7
0
        public Renderer(WriteableBitmap baseBitmap, BaseLighting lighting)
        {
            bmp  = new Bgr24Bitmap(baseBitmap);
            zBuf = new ZBuffer(baseBitmap.PixelWidth, baseBitmap.PixelHeight);
            // 4 stands for RGBA
            backBuffer    = new byte[baseBitmap.PixelWidth * baseBitmap.PixelHeight * 4];
            this.lighting = lighting;

            if (lighting.AmbientColor != null)
            {
                bgColor = lighting.AmbientColor.ToColor();
            }
            else
            {
                lighting.AmbientColor = bgColor.ToVector3();
            }
        }
Пример #8
0
        async Task <bool> DrawMiniatureByMatrix(Matrix4x4 result, Matrix4x4 viewport)
        {
            List <Pixel> pixels = new List <Pixel>();
            //double scale = 400;
            GraphObject graphObject_copy = (GraphObject)globalMiniature.Clone();

            foreach (Group group in globalMiniature.Groups)
            {
                //result = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale));
                WriteableBitmap source = new WriteableBitmap(miniatureWidth, miniatureHeight, 96, 96, PixelFormats.Bgra32, null);
                Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                bitmap.Source.Lock();
                graphObject_copy = (GraphObject)globalMiniature.Clone();
                for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                {
                    Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                    Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                    Vector4 vectorResult = Vector4.Transform(vector, result);
                    vectorResult /= vertex.W;
                    //vectorResult = Vector4.Transform(vectorResult, viewport);
                    vertex.X = vectorResult.X;
                    vertex.Y = vectorResult.Y;
                    vertex.Z = vectorResult.Z;
                    vertex.W = vectorResult.W;
                }
                for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                {
                    VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                    Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                    Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                    vertexNormal.X = vectorResult.X;
                    vertexNormal.Y = vectorResult.Y;
                    vertexNormal.Z = vectorResult.Z;
                }
                //VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                pixels = await GetListAsync(graphObject_copy.Groups[0], minDx, minDy, -1, miniatureWidth, miniatureHeight, bitmap);

                MiniatureModel.Source = bitmap.Source;
                bitmap.Source.Unlock();
                //MiniatureModel.Source = PixelDrawing.GetBitmap(miniatureWidth, miniatureHeight, pixels);
            }
            return(true);
        }
Пример #9
0
        async void DrawModel(GraphObject graphObject, Image targetPlace, int dx, int dy, double scale)
        {
            List <Pixel> pixels           = new List <Pixel>();
            GraphObject  graphObject_copy = (GraphObject)graphObject.Clone();

            Matrix4x4 result;

            foreach (Group group in graphObject.Groups)
            {
                WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                bitmap.Source.Lock();
                result           = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY(0), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale, (float)scale, (float)scale));
                graphObject_copy = (GraphObject)graphObject.Clone();
                for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                {
                    Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                    Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                    Vector4 vectorResult = Vector4.Transform(vector, result);
                    vertex.X = vectorResult.X;
                    vertex.Y = vectorResult.Y;
                    vertex.Z = vectorResult.Z;
                    vertex.W = vectorResult.W;
                }
                for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                {
                    VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                    Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                    Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                    vertexNormal.X = vectorResult.X;
                    vertexNormal.Y = vectorResult.Y;
                    vertexNormal.Z = vectorResult.Z;
                }
                pixels = await GetListAsync(graphObject_copy.Groups[0], dx, dy, -1, windowWidth, windowHeight, bitmap);

                targetPlace.Source = bitmap.Source;
                bitmap.Source.Unlock();
                //targetPlace.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels);
            }
        }
Пример #10
0
 public GouraudShading(Bgr24Bitmap bitmap, Model model, ILighting lighting)
     : base(bitmap, model, lighting)
 {
 }
Пример #11
0
 public PlaneShading(Bgr24Bitmap bitmap, Model model, ILighting lighting)
     : base(bitmap, model)
 {
     _lighting = lighting;
     _zBuffer  = new ZBuffer(_bitmap.PixelWidth, _bitmap.PixelHeight);
 }
Пример #12
0
        private async Task <List <Pixel> > GetListAsync(Group group, int dx, int dy, int viceVersa, int width, int height, Bgr24Bitmap bitmap)
        {
            return(await Task.Run(() =>
            {
                List <Pixel> pixels = new List <Pixel>();
                int count = 0;
                ZBuffer zBuf = new ZBuffer(width, height);
                Parallel.ForEach(group.Faces, face =>
                {
                    if (IsFaceVisible(group.Vertices, face))
                    {
                        List <Pixel> pixelsForSide = new List <Pixel>();
                        List <Pixel> pixelsInSide = new List <Pixel>();
                        Vertex vertex0, vertex1;
                        int index0, index1;

                        Vector3 lightingVector = new Vector3(0, 0, 1);

                        int ind0 = (face.FaceElements.ElementAt(0).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(0).VertexNormalIndex : 1;
                        Vector3 point0Normal = new Vector3(group.VertexNormals[ind0 - 1].X, group.VertexNormals[ind0 - 1].Y, group.VertexNormals[ind0 - 1].Z);

                        int ind1 = (face.FaceElements.ElementAt(1).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(1).VertexNormalIndex : 1;
                        Vector3 point1Normal = new Vector3(group.VertexNormals[ind1 - 1].X, group.VertexNormals[ind1 - 1].Y, group.VertexNormals[ind1 - 1].Z);

                        int ind2 = (face.FaceElements.ElementAt(2).VertexNormalIndex != null) ? (int)face.FaceElements.ElementAt(2).VertexNormalIndex : 1;
                        Vector3 point2Normal = new Vector3(group.VertexNormals[ind2 - 1].X, group.VertexNormals[ind2 - 1].Y, group.VertexNormals[ind2 - 1].Z);

                        Color color = Color.FromArgb(255, 255, 0, 0);
                        Color point1Color = Lambert.GetPointColor(point0Normal, lightingVector, color);
                        Color point2Color = Lambert.GetPointColor(point1Normal, lightingVector, color);
                        Color point3Color = Lambert.GetPointColor(point2Normal, lightingVector, color);
                        Color faceColor = PlaneShading.GetAverageColor(point1Color, point2Color, point3Color);

                        for (int i = 0; i < face.FaceElements.Count - 1; i++)
                        {
                            index0 = (face.FaceElements.ElementAt(i).VertexIndex != -2) ? face.FaceElements.ElementAt(i).VertexIndex : (group.Vertices.Count - 1);
                            index1 = (face.FaceElements.ElementAt(i + 1).VertexIndex != -2) ? face.FaceElements.ElementAt(i + 1).VertexIndex : (group.Vertices.Count - 1);
                            vertex0 = group.Vertices.ElementAt(index0);
                            vertex1 = group.Vertices.ElementAt(index1);
                            pixelsForSide.AddRange(Bresenham.GetPixels((int)(vertex0.X + dx), (int)(vertex0.Y * viceVersa + dy), (int)(vertex0.Z), (int)(vertex1.X + dx), (int)(vertex1.Y * viceVersa + dy), (int)(vertex1.Z), windowWidth, windowHeight, bitmap, zBuf, faceColor));
                        }
                        index0 = (face.FaceElements.ElementAt(0).VertexIndex != -2) ? face.FaceElements.ElementAt(0).VertexIndex : (group.Vertices.Count - 1);
                        index1 = (face.FaceElements.ElementAt(face.FaceElements.Count - 1).VertexIndex != -2) ? face.FaceElements.ElementAt(face.FaceElements.Count - 1).VertexIndex : (group.Vertices.Count - 1);
                        vertex0 = group.Vertices.ElementAt(index0);
                        vertex1 = group.Vertices.ElementAt(index1);
                        pixelsForSide.AddRange(Bresenham.GetPixels((int)(vertex0.X + dx), (int)(vertex0.Y *viceVersa + dy), vertex0.Z, (int)(vertex1.X + dx), (int)(vertex1.Y *viceVersa + dy), vertex1.Z, windowWidth, windowHeight, bitmap, zBuf, faceColor));


                        RastAlgorithm.DrawPixelForRasterization(pixelsForSide, bitmap, zBuf, faceColor);
                        //pixels.AddRange(pixelsForSide);
                        //pixelsInSide.AddRange(RastAlgorithm.DrawPixelForRasterization(pixelsForSide, bitmap, zBuf));
                        //pixels.AddRange(pixelsInSide);
                        count++;
                    }
                });
                return pixels;
            }));
        }
Пример #13
0
        public async void ImageButton_Click(object sender, RoutedEventArgs e)
        {
            Parser       parser      = new Parser();
            GraphObject  graphObject = parser.ParseFile(filePath);
            List <Pixel> pixels      = new List <Pixel>();

            if (!isApplyOptions)
            {
                double      value            = 5 * Math.PI / 180;
                GraphObject graphObject_copy = (GraphObject)graphObject.Clone();

                Matrix4x4 result;
                foreach (Group group in graphObject.Groups)
                {
                    while (value < 10000)
                    {
                        WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                        Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                        bitmap.Source.Lock();
                        result           = GetResultMatrix(Matrix4x4.CreateTranslation(0, 0, 0), Matrix4x4.CreateRotationX(0), Matrix4x4.CreateRotationY((float)(value)), Matrix4x4.CreateRotationZ(0), Matrix4x4.CreateScale((float)scale * 2, (float)scale * 2, (float)scale * 2));
                        graphObject_copy = (GraphObject)graphObject.Clone();
                        for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                        {
                            Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                            Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                            Vector4 vectorResult = Vector4.Transform(vector, result);
                            vertex.X = vectorResult.X;
                            vertex.Y = vectorResult.Y;
                            vertex.Z = vectorResult.Z;
                            vertex.W = vectorResult.W;
                        }
                        for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                        {
                            VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                            Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                            Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                            vertexNormal.X = vectorResult.X;
                            vertexNormal.Y = vectorResult.Y;
                            vertexNormal.Z = vectorResult.Z;
                        }
                        pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap);

                        //GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels);
                        value += 1 * Math.PI / 180;
                        GraphicModel.Source = bitmap.Source;
                        bitmap.Source.Unlock();
                    }
                }
            }
            else
            {
                TransformOptions options          = GetUserOptions(scale * 2);
                GraphObject      graphObject_copy = (GraphObject)graphObject.Clone();

                Matrix4x4 result, viewport;
                foreach (Group group in graphObject.Groups)
                {
                    WriteableBitmap source = new WriteableBitmap(windowWidth, windowHeight, 96, 96, PixelFormats.Bgra32, null);
                    Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);
                    bitmap.Source.Lock();
                    result           = GetOptionsMatrix(options, windowWidth, windowHeight);
                    viewport         = GetViewPort(0, 0, windowWidth, windowHeight);
                    graphObject_copy = (GraphObject)graphObject.Clone();
                    for (int i = 0; i < graphObject_copy.Groups[0].Vertices.Count; i++)
                    {
                        Vertex  vertex       = graphObject_copy.Groups[0].Vertices[i];
                        Vector4 vector       = new Vector4(vertex.X, vertex.Y, vertex.Z, vertex.W);
                        Vector4 vectorResult = Vector4.Transform(vector, result);
                        vectorResult /= vertex.W;
                        //vectorResult = Vector4.Transform(vectorResult, viewport);
                        vertex.X = vectorResult.X;
                        vertex.Y = vectorResult.Y;
                        vertex.Z = vectorResult.Z;
                        vertex.W = vectorResult.W;
                    }
                    for (int i = 0; i < graphObject_copy.Groups[0].VertexNormals.Count; i++)
                    {
                        VertexNormal vertexNormal = graphObject_copy.Groups[0].VertexNormals[i];
                        Vector3      vector       = new Vector3(vertexNormal.X, vertexNormal.Y, vertexNormal.Z);
                        Vector3      vectorResult = Vector3.Normalize(Vector3.TransformNormal(vector, result));
                        vertexNormal.X = vectorResult.X;
                        vertexNormal.Y = vectorResult.Y;
                        vertexNormal.Z = vectorResult.Z;
                    }
                    pixels = await GetListAsync(graphObject_copy.Groups[0], maxDx, maxDy, -1, windowWidth, windowHeight, bitmap);

                    GraphicModel.Source = bitmap.Source;
                    bitmap.Source.Unlock();

                    //if (pixels != null) { GraphicModel.Source = PixelDrawing.GetBitmap(windowWidth, windowHeight, pixels); }
                }
            }
        }
 public BresenhamAlg(Bgr24Bitmap bitmap, Model model)
 {
     _bitmap = bitmap;
     _model  = model;
 }
Пример #15
0
        private void DrawButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                textureEnabled(false);
                if (model != null)
                {
                    WriteableBitmap source = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
                    Bgr24Bitmap     bitmap = new Bgr24Bitmap(source);

                    ModelParams modelParams = GetModelsParams();
                    Model       modelMain   = model.Clone() as Model;

                    CoordTransformations.TransformFromWorldToView(modelMain, modelParams);

                    if (modelMain.CheckSize(width, height))
                    {
                        Color   color    = Color.FromRgb(byte.Parse(colorRTextBox.Text), byte.Parse(colorGTextBox.Text), byte.Parse(colorBTextBox.Text));
                        Vector3 lighting = new Vector3(int.Parse(lightVectorXTextBox.Text), int.Parse(lightVectorYTextBox.Text), -int.Parse(lightVectorZTextBox.Text));

                        if (bresenhamRadioButton.IsChecked == true)
                        {
                            // lab 1-2
                            BresenhamAlg bresenham = new BresenhamAlg(bitmap, modelMain);
                            bresenham.DrawModel(color);
                        }
                        else if (plainShadingRadioButton.IsChecked == true)
                        {
                            // lab 3
                            PlaneShading shader = new PlaneShading(bitmap, modelMain, new LambertLighting(lighting));
                            shader.DrawModel(color);
                        }

                        else if (phongShadingRadioButton.IsChecked == true)
                        {
                            textureEnabled(true);
                            // затенение фонга
                            Vector3 viewVector = new Vector3(int.Parse(colorRTextBox_View.Text), int.Parse(colorGTextBox_View.Text), int.Parse(colorBTextBox_View.Text));
                            Vector3 koef_a = new Vector3(float.Parse(colorRTextBox_A.Text), float.Parse(colorGTextBox_A.Text), float.Parse(colorBTextBox_A.Text));
                            Vector3 koef_d = new Vector3(float.Parse(colorRTextBox_D.Text), float.Parse(colorGTextBox_D.Text), float.Parse(colorBTextBox_D.Text));
                            Vector3 koef_s = new Vector3(float.Parse(colorRTextBox_S.Text), float.Parse(colorGTextBox_S.Text), float.Parse(colorBTextBox_S.Text));
                            Vector3 ambientColor = new Vector3(int.Parse(colorRTextBox_Ambient.Text), int.Parse(colorGTextBox_Ambient.Text), int.Parse(colorBTextBox_Ambient.Text));
                            Vector3 reflectionColor = new Vector3(int.Parse(colorRTextBox_Reflection.Text), int.Parse(colorGTextBox_Reflecion.Text), int.Parse(colorBTextBox_Reflection.Text));
                            float   shiness = float.Parse(shinessBox.Text);
                            bool    d = false, n = false, s = false;
                            if ((diffuseCheckBox != null && (bool)diffuseCheckBox.IsChecked))
                            {
                                d = true;
                            }
                            if ((normalCheckBox != null && (bool)normalCheckBox.IsChecked))
                            {
                                n = true;
                            }
                            if ((mirrorCheckBox != null && (bool)mirrorCheckBox.IsChecked))
                            {
                                s = true;
                            }

                            var light = new PhongLighting(lighting, viewVector, koef_a, koef_d, koef_s, ambientColor, reflectionColor, shiness, d, n, s);
                            //var light = new LambertLighting(lighting);
                            PhongShading shader = new PhongShading(bitmap, modelMain, light, d, n, s);
                            shader.DrawModel(color);
                        }


                        screenPictureBox.Source = bitmap.Source;
                    }
                }
                else
                {
                    MessageBox.Show("Load an object");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Произошла ошибка! " + ex);
            }
        }