Esempio n. 1
0
        public Canvas Project3D()
        {
            Draw3D D3D = new Draw3D();

            projectPoint = new Point3D();

            if (zoom < 1)
            {
                zoom = 1;
            }

            scale = (centerX / zoom);

            scalePoint = new Point3D(scale, scale, scale);

            projectPoint = D3D.DrawAzimuth(currentPoint, elevation, azimuth, rotaPoint, movePoint, scalePoint);

            renderDepth = (projectPoint.Z / centerX);

            //starGFX.Margin = new Thickness(-(starGFX.Width / 2), -(starGFX.Height / 2), 0, 0);

            //starSEL.Margin = new Thickness(-(starGFX.Width * 1.5) / 2, -(starGFX.Height * 1.5) / 2, 0, 0);

            starCanvas.Margin = new Thickness(centerX + projectPoint.X, centerY + projectPoint.Y, 0, 0);

            return(starCanvas);
        }
Esempio n. 2
0
        private void DrawTriangle(Vertex v1, Vertex v2, Vertex v3)
        {
            //var v1 = primitive.Vertices[triangle.Vertex1];
            //var v2 = primitive.Vertices[triangle.Vertex2];
            //var v3 = primitive.Vertices[triangle.Vertex3];

            var vec1 = new Vector4(v1.X, v1.Y, v1.Z, 1);
            var vec2 = new Vector4(v2.X, v2.Y, v2.Z, 1);
            var vec3 = new Vector4(v3.X, v3.Y, v3.Z, 1);

            Vector3f faceNormal = Math3D.CalculateNormal(Math3D.ConvertToDecart(vec1), Math3D.ConvertToDecart(vec2), Math3D.ConvertToDecart(vec3));

            var worldCoord1 = _modelMatrix * new Vector4(v1.X, v1.Y, v1.Z, 1);
            var worldCoord2 = _modelMatrix * new Vector4(v2.X, v2.Y, v2.Z, 1);
            var worldCoord3 = _modelMatrix * new Vector4(v3.X, v3.Y, v3.Z, 1);

            ShaderProgram.ComputeVertex(new VertexInput {
                Position = new Vector4(v1.X, v1.Y, v1.Z, 1), Normal = (Vector4)faceNormal
            });
            ShaderProgram.ComputeVertex(new VertexInput {
                Position = new Vector4(v1.X, v1.Y, v1.Z, 1), Normal = (Vector4)faceNormal
            });
            ShaderProgram.ComputeVertex(new VertexInput {
                Position = new Vector4(v1.X, v1.Y, v1.Z, 1), Normal = (Vector4)faceNormal
            });

            Draw3D.SimpleRasterizeTriangle(
                ConvertToScreenCoord0(decartvector1),
                ConvertToScreenCoord0(decartvector2),
                ConvertToScreenCoord0(decartvector3),
                FrameBuffer,
                Color.FromArgb((int)(255 * Restrict(sampleColor.X)), (int)(255 * Restrict(sampleColor.Y)), (int)(255 * Restrict(sampleColor.Z))),
                _zBuffer);
        }
Esempio n. 3
0
        public void InitStar()
        {
            Draw3D D3D = new Draw3D();

            Point3D projectPoint = new Point3D();

            starGFX.Width  = 2;
            starGFX.Height = 2;

            scale = (centerX / zoom);

            if (scale < 1)
            {
                scale = 1;
            }

            scalePoint = new Point3D(scale, scale, scale);

            projectPoint = D3D.DrawAzimuth(currentPoint, elevation, azimuth, rotaPoint, movePoint, scalePoint);

            renderDepth = (projectPoint.Z / centerX);

            distanceDepth = (distance / zoom);

            renderD = starColor.Color.ScA * (float)(distanceDepth);
        }
Esempio n. 4
0
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try {
                using (Draw3D d3d = new Draw3D()) {
                    d3d.Run();
                }
            }
            catch (Exception ex) {
                Debug.Assert(false, ex.ToString(), Environment.StackTrace.ToString());
            }
        }
Esempio n. 5
0
        private Line DrawLine(Point3D start, Point3D end, double elevation, double azimuth, double reverse = 1, Point3D rotationPoint = default(Point3D))
        {
            Draw3D D3D = new Draw3D();

            Line returnLine = new Line();

            Point3D startPoint = D3D.DrawAzimuth(start, elevation, azimuth, rotationPoint);
            Point3D endPoint   = D3D.DrawAzimuth(end, elevation, azimuth, rotationPoint);

            returnLine.X1 = (startPoint.X * reverse) + centerX;
            returnLine.X2 = (endPoint.X * reverse) + centerY;

            returnLine.Y1 = (startPoint.Y * reverse) + centerY;
            returnLine.Y2 = (endPoint.Y * reverse) + centerY;

            depthPoint = startPoint;

            return(returnLine);
        }
Esempio n. 6
0
        public MainWindow()
        {
            InitializeComponent();

            Draw3D draw = new Draw3D(mainCanvas);

            Point3D p0 = new Point3D(0, 0, 0);
            Point3D p1 = new Point3D(10, 0, 0);

            draw.shapes.AddLine(p0, p1);
            draw.shapes.AddSphere(p0, 10, 12);

            draw.IsOnZoomPan_WheelScroll = true;

            draw.RegenerateShapes_ModelVisual3ds();
            draw.RedrawShapes();

            //Example_CanvasText();


            draw.ViewTop();



            // Declare scene objects.
            Viewport3D      myViewport3D    = new Viewport3D();
            Model3DGroup    myModel3DGroup  = new Model3DGroup();
            GeometryModel3D myGeometryModel = new GeometryModel3D();
            ModelVisual3D   myModelVisual3D = new ModelVisual3D();
            // Defines the camera used to view the 3D object. In order to view the 3D object,
            // the camera must be positioned and pointed such that the object is within view
            // of the camera.
            PerspectiveCamera myPCamera = new PerspectiveCamera();

            // Specify where in the 3D scene the camera is.
            myPCamera.Position = new Point3D(0, 0, 2);

            // Specify the direction that the camera is pointing.
            myPCamera.LookDirection = new Vector3D(0, 0, -1);

            // Define camera's horizontal field of view in degrees.
            myPCamera.FieldOfView = 60;

            // Asign the camera to the viewport
            myViewport3D.Camera = myPCamera;
            // Define the lights cast in the scene. Without light, the 3D object cannot
            // be seen. Note: to illuminate an object from additional directions, create
            // additional lights.
            DirectionalLight myDirectionalLight = new DirectionalLight();

            myDirectionalLight.Color     = Colors.White;
            myDirectionalLight.Direction = new Vector3D(-0.61, -0.5, -0.61);

            myModel3DGroup.Children.Add(myDirectionalLight);

            // The geometry specifes the shape of the 3D plane. In this sample, a flat sheet
            // is created.
            MeshGeometry3D myMeshGeometry3D = new MeshGeometry3D();

            // Create a collection of normal vectors for the MeshGeometry3D.
            Vector3DCollection myNormalCollection = new Vector3DCollection();

            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myNormalCollection.Add(new Vector3D(0, 0, 1));
            myMeshGeometry3D.Normals = myNormalCollection;

            // Create a collection of vertex positions for the MeshGeometry3D.
            Point3DCollection myPositionCollection = new Point3DCollection();

            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, -0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, 0.5, 0.5));
            myPositionCollection.Add(new Point3D(-0.5, -0.5, 0.5));
            myMeshGeometry3D.Positions = myPositionCollection;

            // Create a collection of texture coordinates for the MeshGeometry3D.
            PointCollection myTextureCoordinatesCollection = new PointCollection();

            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 0));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(1, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 1));
            myTextureCoordinatesCollection.Add(new Point(0, 0));
            myMeshGeometry3D.TextureCoordinates = myTextureCoordinatesCollection;

            // Create a collection of triangle indices for the MeshGeometry3D.
            Int32Collection myTriangleIndicesCollection = new Int32Collection();

            myTriangleIndicesCollection.Add(0);
            myTriangleIndicesCollection.Add(1);
            myTriangleIndicesCollection.Add(2);
            myTriangleIndicesCollection.Add(3);
            myTriangleIndicesCollection.Add(4);
            myTriangleIndicesCollection.Add(5);
            myMeshGeometry3D.TriangleIndices = myTriangleIndicesCollection;

            // Apply the mesh to the geometry model.
            myGeometryModel.Geometry = myMeshGeometry3D;

            // The material specifies the material applied to the 3D object. In this sample a
            // linear gradient covers the surface of the 3D object.

            // Create a horizontal linear gradient with four stops.
            LinearGradientBrush myHorizontalGradient = new LinearGradientBrush();

            myHorizontalGradient.StartPoint = new Point(0, 0.5);
            myHorizontalGradient.EndPoint   = new Point(1, 0.5);
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Red, 0.25));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.Blue, 0.75));
            myHorizontalGradient.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0));

            // Define material and apply to the mesh geometries.
            DiffuseMaterial myMaterial = new DiffuseMaterial(myHorizontalGradient);

            myGeometryModel.Material = myMaterial;

            // Apply a transform to the object. In this sample, a rotation transform is applied,
            // rendering the 3D object rotated.
            RotateTransform3D   myRotateTransform3D   = new RotateTransform3D();
            AxisAngleRotation3D myAxisAngleRotation3d = new AxisAngleRotation3D();

            myAxisAngleRotation3d.Axis   = new Vector3D(0, 3, 0);
            myAxisAngleRotation3d.Angle  = 40;
            myRotateTransform3D.Rotation = myAxisAngleRotation3d;
            myGeometryModel.Transform    = myRotateTransform3D;

            // Add the geometry model to the model group.
            myModel3DGroup.Children.Add(myGeometryModel);

            // Add the group of models to the ModelVisual3d.
            myModelVisual3D.Content = myModel3DGroup;

            //
            myViewport3D.Children.Add(myModelVisual3D);

            // Apply the viewport to the page so it will be rendered.
            Content = myViewport3D;
        }
Esempio n. 7
0
        public void DrawTriangles_SubpixelAccuracity()
        {
            var form = new TestForm();

            form.ClientSize = new Size(300, 300);

            var vertex1 = new Vector3f(1f, 1f, 0);
            var vertex2 = new Vector3f(5f, 1f, 0);
            var vertex3 = new Vector3f(5f, 5f, 0);

            form.Paint += (object sender, PaintEventArgs e) =>
            {
                e.Graphics.Clear(Color.Black);
                e.Graphics.SmoothingMode     = SmoothingMode.None;
                e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;

                Bitmap bmp     = new Bitmap(15, 15);
                var    zbuffer = new double[15 * 15];

                //Проверяем прямой порядок вершин по у
                Draw3D.SimpleRasterizeTriangle(vertex1, vertex2, vertex3, bmp, Color.Green, zbuffer);

                var imageScale = 20;

                DrawBitmap(e.Graphics, bmp, new Rectangle(0, 0, 300, 300));

                DrawGrid(new Pen(Color.Gray), e.Graphics, 15, 15, 300, 300);
                DrawBoundTriangle(new Pen(Color.Red), e.Graphics, vertex1, vertex2, vertex3, imageScale);
            };

            form.KeyDown += (object sender, KeyEventArgs e) =>
            {
                if (e.KeyCode == Keys.A)
                {
                    vertex1.X -= 0.05f;
                }
                if (e.KeyCode == Keys.D)
                {
                    vertex1.X += 0.05f;
                }

                if (e.KeyCode == Keys.W)
                {
                    vertex2.Y -= 0.05f;
                }
                if (e.KeyCode == Keys.S)
                {
                    vertex2.Y += 0.05f;
                }

                if (e.KeyCode == Keys.Left)
                {
                    vertex1.X -= 0.05f;
                    vertex2.X -= 0.05f;
                    vertex3.X -= 0.05f;
                }
                if (e.KeyCode == Keys.Right)
                {
                    vertex1.X += 0.05f;
                    vertex2.X += 0.05f;
                    vertex3.X += 0.05f;
                }

                if (e.KeyCode == Keys.Up)
                {
                    vertex1.Y -= 0.05f;
                    vertex2.Y -= 0.05f;
                    vertex3.Y -= 0.05f;
                }
                if (e.KeyCode == Keys.Down)
                {
                    vertex1.Y += 0.05f;
                    vertex2.Y += 0.05f;
                    vertex3.Y += 0.05f;
                }

                form.Refresh();
            };

            Application.Run(form);
        }
Esempio n. 8
0
        public void Render(Scene scene)
        {
            //TransformedVector = TranslationMatrix * RotationMatrix * ScaleMatrix * OriginalVector;
            //MVPmatrix = projection * view * model;

            double[] zBuffer = new double[_screenWidth * _screenHeight];

            var rnd       = new Random();
            var cvvMatrix = Math3D.GetPerspectiveMatrix(100, _halfScreenWidth / _halfscreenHeight, 0.3d, 1000d);

            foreach (var primitive in scene.Objects)
            {
                var rotationMatrix = Math3D.GetRotationMatrix(
                    primitive.Rotation.X,
                    primitive.Rotation.Y,
                    primitive.Rotation.Z);

                var translationMatrix = Math3D.GetTranslationMatrix(primitive.Position.X, primitive.Position.Y, primitive.Position.Z);

                var scaleMatrix = Math3D.GetScaleMatrix(1, 1, 1);
                var modelMatrix = translationMatrix * (rotationMatrix * scaleMatrix);
                var viewMatrix  = Math3D.GetViewMatrix(new Vector3f(0f, 1.2f, -2f), new Vector3f(0, 0f, 0f));

                var transformMatrix = cvvMatrix * viewMatrix;// * modelMatrix;

                foreach (var triangle in primitive.Faces)
                {
                    var v1 = primitive.Vertices[triangle.Vertex1];
                    var v2 = primitive.Vertices[triangle.Vertex2];
                    var v3 = primitive.Vertices[triangle.Vertex3];

                    //TODO Здесь нужен вызов фрагментного шейдера
                    //shader.Set(v1,v2,v3) shader.Compute()

                    #region Завернуть в шейдер
                    var worldCoord1 = modelMatrix * new Vector4(v1.X, v1.Y, v1.Z, 1);
                    var worldCoord2 = modelMatrix * new Vector4(v2.X, v2.Y, v2.Z, 1);
                    var worldCoord3 = modelMatrix * new Vector4(v3.X, v3.Y, v3.Z, 1);

                    var vector1 = transformMatrix * worldCoord1;
                    var vector2 = transformMatrix * worldCoord2;
                    var vector3 = transformMatrix * worldCoord3;

                    var decartvector1 = Math3D.ConvertToDecart(vector1);
                    var decartvector2 = Math3D.ConvertToDecart(vector2);
                    var decartvector3 = Math3D.ConvertToDecart(vector3);

                    Vector3f faceNormalInWorldCoord = Math3D.CalculateNormal(Math3D.ConvertToDecart(worldCoord1), Math3D.ConvertToDecart(worldCoord2), Math3D.ConvertToDecart(worldCoord3));

                    Vector3f faceNormalInProjectionCoord = SimpleRender.Math.Vector3f.CrossProductLeft((decartvector3 - decartvector1), (decartvector2 - decartvector1));
                    faceNormalInProjectionCoord = faceNormalInProjectionCoord.Normalize();
                    var    viewDirection = new Vector4(0, 0, -1, 1);
                    double intensity     = Math3D.DotProduct(faceNormalInProjectionCoord, viewDirection);

                    //TODO Подумать нужноли это в шейдере
                    if (intensity <= 0)
                    {
                        continue;
                    }

                    //ambient = Ka,
                    //diffuse = Kd * cos(N, L),
                    //specular = Ks * pow(cos(R, V), Ns),
                    //intensity = ambient + amp * (diffuse + specular).

                    //-----------------
                    //http://www.gamedev.ru/code/articles/HLSL?page=4
                    //Lighting:
                    //Lambert (ambient lighting)
                    //Diffuse (diffuse lighting model)
                    //Phong (specular lighting model), Blinn (blinn specular lighting model)
                    //Sum of this

                    //Реалистичное освещение на основе Кука-Торренса

                    //-------------

                    var ligthSource         = scene.LightSources.First();
                    var globalLightPosition = ligthSource.Position.Normalize();

                    double illuminationIntensity = Math3D.DotProduct(faceNormalInWorldCoord, globalLightPosition);
                    var    diffuseColor          = new Vector4(
                        primitive.Mategial.DiffuseColor.X * ligthSource.Color.X,
                        primitive.Mategial.DiffuseColor.Y * ligthSource.Color.Y,
                        primitive.Mategial.DiffuseColor.Z * ligthSource.Color.Z,
                        1)
                                                   * illuminationIntensity;

                    //var reflection = (Vector3f.CrossProductLeft(faceNormalInWorldCoord ,
                    //    (Vector3f.CrossProductLeft(faceNormalInWorldCoord ,globalLightPosition) * 2.0f)) -
                    //    globalLightPosition).Normalize();   // reflected light

                    var sampleColor = scene.AmbientColor + diffuseColor * ligthSource.Intensity;

                    #endregion

                    Draw3D.SimpleRasterizeTriangle(
                        ConvertToScreenCoord0(decartvector1),
                        ConvertToScreenCoord0(decartvector2),
                        ConvertToScreenCoord0(decartvector3),
                        Image,
                        Color.FromArgb((int)(255 * Restrict(sampleColor.X)), (int)(255 * Restrict(sampleColor.Y)), (int)(255 * Restrict(sampleColor.Z))),
                        zBuffer);
                }
            }
        }