public Camera() { FieldOfView = Math.PI / 4; AspectRatio = 1; NearPlane = 1; FarPlane = 100; UpVector = VectorHelpers.Create(0, 1, 0); Position = VectorHelpers.Create(0, 0, 0); LookAt = VectorHelpers.Create(0, 0, -1); }
public Scene(Renderer renderer) { _renderer = renderer; _fieldObj = ObjData.LoadFromFile("Data/Models/cube.obj"); _boardboxObj = ObjData.LoadFromFile("Data/Models/boardbox.obj"); _pawnObj = ObjData.LoadFromFile("Data/Models/pawn.obj"); _activeCamera = new Camera(); _activeCamera.NearPlane = 0.1; _activeCamera.FarPlane = 200.0; _activeCamera.Position = VectorHelpers.Create(0, 10, -20); _activeCamera.LookAt = VectorHelpers.Create(0, 0, 0); _activeCamera.UpVector = VectorHelpers.Create(0, 1, 0); _secondaryCamera = new Camera(); _secondaryCamera.NearPlane = 0.1; _secondaryCamera.FarPlane = 200.0; _secondaryCamera.Position = VectorHelpers.Create(0, 5, -20); _secondaryCamera.LookAt = VectorHelpers.Create(0, 0, 0); _secondaryCamera.UpVector = VectorHelpers.Create(0, 1, 0); _renderer.Lights.Add(new PointLight { Position = VectorHelpers.Create(0, 10, -20), Color = Colors.White, }); //_renderer.Lights.Add(new PointLight //{ // Position = VectorHelpers.Create(-10, 1.5, 0), // Color = Colors.Blue, //}); //_renderer.Lights.Add(new PointLight //{ // Position = VectorHelpers.Create(0, 10, 0), // Color = Colors.White, //}); _materials = new List <Material>(); _materials.Add(new Material { AmbientColor = Colors.Black, DiffuseColor = Colors.Chartreuse, SpecularColor = Colors.Gray, DiffuseTexture = new WriteableBitmap(new BitmapImage(new Uri("Data/Textures/darkstone.png", UriKind.Relative))), ShineFactor = 128.0, }); _materials.Add(new Material { AmbientColor = Colors.Black, DiffuseColor = Colors.White, SpecularColor = Colors.Gray, ShineFactor = 1, }); _materials.Add(new Material { AmbientColor = Color.FromRgb(16, 16, 16), DiffuseColor = Colors.RosyBrown, SpecularColor = Colors.White, DiffuseTexture = new WriteableBitmap(new BitmapImage(new Uri("Data/Textures/wood.png", UriKind.Relative))), ShineFactor = 1.0, }); _materials.Add(new Material { AmbientColor = Colors.Black, DiffuseColor = Colors.DarkRed, SpecularColor = Colors.Yellow, ShineFactor = 64.0, }); }
public static ObjData LoadFromFile(string filePath) { using (var streamReader = new StreamReader(filePath)) { var obj = new ObjData(); string line = null; while ((line = streamReader.ReadLine()) != null) { if (String.IsNullOrWhiteSpace(line)) { continue; } if (line[0] == '#') { continue; } var tokens = line.Split(' '); switch (tokens[0]) { case "v": { double x = Double.Parse(tokens[1], CultureInfo.InvariantCulture); double y = Double.Parse(tokens[2], CultureInfo.InvariantCulture); double z = Double.Parse(tokens[3], CultureInfo.InvariantCulture); obj.Vertices.Add(VectorHelpers.Create(x, y, z)); break; } case "vt": { double u = Double.Parse(tokens[1], CultureInfo.InvariantCulture); double v = Double.Parse(tokens[2], CultureInfo.InvariantCulture); obj.TexCoords.Add(VectorHelpers.Create(u, v)); break; } case "vn": { double x = Double.Parse(tokens[1], CultureInfo.InvariantCulture); double y = Double.Parse(tokens[2], CultureInfo.InvariantCulture); double z = Double.Parse(tokens[3], CultureInfo.InvariantCulture); obj.Normals.Add(VectorHelpers.Create(x, y, z)); break; } case "f": { var triangle = new IndexedTriangle(); for (int i = 0; i < 3; ++i) { var vertexTokens = tokens[i + 1].Split('/'); triangle.Vertices[i] = Int32.Parse(vertexTokens[0]) - 1; triangle.TexCoords[i] = Int32.Parse(vertexTokens[1]) - 1; triangle.Normals[i] = Int32.Parse(vertexTokens[2]) - 1; } obj.Triangles.Add(triangle); break; } } } return(obj); } }
public void RenderObjMesh(ObjData meshToRender, Matrix <double> transformation, Matrix <double> normalTransformation) { if (Material == null) { Material = new Material(); } if (TexturingEnabled) { if (Material.DiffuseTexture != null) { Material.DiffuseTexture.Lock(); } } var hw = _renderWindow.Framebuffer.PixelWidth * 0.5; var hh = _renderWindow.Framebuffer.PixelHeight * 0.5; foreach (var triangle in meshToRender.Triangles) { var tri = new PreparedTriangle(); for (int i = 0; i < 3; ++i) { Vector <double> modelSpacePosition = meshToRender.Vertices[triangle.Vertices[i]]; Vector <double> modelSpaceNormal = meshToRender.Normals[triangle.Normals[i]]; Vector <double> screenSpacePosition = (transformation * modelSpacePosition.ExtendVector()) .ToCartesian() .Add(VectorHelpers.Create(1.0, 1.0, 0.0)) .PointwiseMultiply(VectorHelpers.Create(hw, hh, 1.0)); Vector <double> worldSpacePosition = (normalTransformation * modelSpacePosition.ExtendVector()) .ToCartesian(); Vector <double> worldSpaceNormal = (normalTransformation * modelSpaceNormal.ExtendVector(0.0)) .DiscardLastCoordinate().Normalize(2); // Vertex shader tri.Vertices[i].SetCoordinates(screenSpacePosition); tri.Vertices[i].SetTextureCoordinates(meshToRender.TexCoords[triangle.TexCoords[i]]); var vR = 0; var vG = 0; var vB = 0; if (AmbientLightingEnabled) { vR += Material.AmbientColor.R; vG += Material.AmbientColor.G; vB += Material.AmbientColor.B; } if (DiffuseLightingEnabled || SpecularLightingEnabled) { foreach (var light in Lights) { var lightDirection = (light.Position - worldSpacePosition).Normalize(2); if (DiffuseLightingEnabled) { var diffuseLightFactor = Math.Max(lightDirection.DotProduct(worldSpaceNormal), 0); var fullSaturationDiffuseColor = MultiplyColors(light.Color, Material.DiffuseColor); vR += (byte)(fullSaturationDiffuseColor.R * diffuseLightFactor); vG += (byte)(fullSaturationDiffuseColor.G * diffuseLightFactor); vB += (byte)(fullSaturationDiffuseColor.B * diffuseLightFactor); } if (SpecularLightingEnabled) { var eyeDirection = (WorldPositionEye - worldSpacePosition).Normalize(2); var reflected = (2 * worldSpaceNormal.DotProduct(lightDirection) * worldSpaceNormal - lightDirection).Normalize(2); var specularLightFactor = Math.Pow(Math.Max(eyeDirection.DotProduct(reflected), 0), Material.ShineFactor); var fullSaturationSpecularColor = MultiplyColors(light.Color, Material.SpecularColor); vR += (byte)(fullSaturationSpecularColor.R * specularLightFactor); vG += (byte)(fullSaturationSpecularColor.G * specularLightFactor); vB += (byte)(fullSaturationSpecularColor.B * specularLightFactor); } } } tri.Vertices[i].VertexColor = Color.FromRgb( (byte)Math.Min(vR, 255), (byte)Math.Min(vG, 255), (byte)Math.Min(vB, 255)); // End of vertex shader } DrawScreenSpaceTriangleInterpolated(tri); } if (TexturingEnabled && Material.DiffuseTexture != null) { Material.DiffuseTexture.Unlock(); } }