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); }
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); }
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); }
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()); } }
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); }
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; }
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); }
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); } } }