private static void Draw(WritableTexture screen, Func <Shader> shaderFactory, FaceDrawer faceDrawer, int startY, int endY, World world) { var shaderState = new ShaderState(30, world); var shader = shaderFactory(); shader.World(world); for (var i = 0; i < world.WorldObject.Model.Geometry.Faces.Count; i++) { faceDrawer.Draw(i, screen, shader, shaderState, startY, endY); } }
private async Task TwoPhaseDraw(World world, Tuple <int, int>[] regions, WritableTexture screen) { _firstPhaseScreen.Clear(); _faceDrawer.Init(RenderMode.Fill); var firstPhaseTasks = regions.Select( region => new Task( () => Draw(_firstPhaseScreen, world.WorldObject.FirstPhaseShaderFactory, _faceDrawer, region.Item1, region.Item2, world))) .ToArray(); foreach (var task in firstPhaseTasks) { task.Start(); } await Task.WhenAll(firstPhaseTasks).ConfigureAwait(false); _faceDrawer.Init(world.RenderMode); var secondPhaseTasks = regions.Select( region => new Task(() => { var shaderState = new ShaderState(30, world); var shader = world.WorldObject.ShaderFactory(); shader.World(world, _firstPhaseScreen); for (var i = 0; i < world.WorldObject.Model.Geometry.Faces.Count; i++) { _faceDrawer.Draw(i, screen, shader, shaderState, region.Item1, region.Item2); } })) .ToArray(); foreach (var task in secondPhaseTasks) { task.Start(); } await Task.WhenAll(secondPhaseTasks).ConfigureAwait(false); }
public void Draw(int faceIndex, WritableTexture screen, Shader shader, ShaderState shaderState, int startY, int endY) { var faceState = shaderState.Face; var vertexState = shaderState.Vertex; var fragmentState = shaderState.Fragment; faceState.Clear(); vertexState.Clear(); shader.Face(faceState, faceIndex); var v04 = shader.Vertex(vertexState, faceIndex, 0); var v14 = shader.Vertex(vertexState, faceIndex, 1); var v24 = shader.Vertex(vertexState, faceIndex, 2); var v0 = new Vector3(v04.X / v04.W, v04.Y / v04.W, v04.Z / v04.W); var v1 = new Vector3(v14.X / v14.W, v14.Y / v14.W, v14.Z / v14.W); var v2 = new Vector3(v24.X / v24.W, v24.Y / v24.W, v24.Z / v24.W); var diff1 = Vector3.Subtract(v1, v0); var diff2 = Vector3.Subtract(v2, v1); var normal = Vector3.Cross(diff1, diff2); normal = Vector3.Normalize(normal); var directionCulling = Vector3.Dot(normal, new Vector3(0, 0, 1)); if (directionCulling <= 0) { return; } if (_useFill) { DrawFilling(screen, startY, endY, v0, v1, v2, fragmentState, faceState, vertexState, shader); } if (_useBorders) { DrawBorders(faceIndex, screen, shader, shaderState, startY, endY); } }
private void DrawBorders(int faceIndex, WritableTexture screen, Shader shader, ShaderState shaderState, int startY, int endY) { shaderState.Vertex.Clear(); var v0 = shader.Vertex(shaderState.Vertex, faceIndex, 0); var v1 = shader.Vertex(shaderState.Vertex, faceIndex, 1); var v2 = shader.Vertex(shaderState.Vertex, faceIndex, 2); var screenCoords = new[] { new Vector3(v0.X / v0.W, v0.Y / v0.W, v0.Z / v0.W), new Vector3(v1.X / v1.W, v1.Y / v1.W, v1.Z / v1.W), new Vector3(v2.X / v2.W, v2.Y / v2.W, v2.Z / v2.W) }; DrawSolidLine((int)screenCoords[0].X, (int)screenCoords[0].Y, (int)screenCoords[1].X, (int)screenCoords[1].Y, screen, _borderColor, startY, endY); DrawSolidLine((int)screenCoords[1].X, (int)screenCoords[1].Y, (int)screenCoords[2].X, (int)screenCoords[2].Y, screen, _borderColor, startY, endY); DrawSolidLine((int)screenCoords[2].X, (int)screenCoords[2].Y, (int)screenCoords[0].X, (int)screenCoords[0].Y, screen, _borderColor, startY, endY); }