public void Initialize(int width, int height) { _buffers = BufferManager.Instance.Create<FrameBuffer>(width, height); FramebufferBitmap = new WriteableBitmap(width, height); _initialized = true; BackgroundColor = Color.FromArgb(0xff, 0, 0, 0); }
public static void DrawLine(Viewport viewport, IBuffers buffers, int xstart, int ystart, int xend, int yend, Color color) { var colorAsInt = (int)color.ToUInt32(); var deltaX = xend - xstart; var deltaY = yend - ystart; var lengthX = deltaX >= 0 ? deltaX : -deltaX; var lengthY = deltaY >= 0 ? deltaY : -deltaY; var actualLength = lengthX > lengthY ? lengthX : lengthY; if( actualLength != 0 ) { var slopeX = (float) deltaX/(float) actualLength; var slopeY = (float) deltaY/(float) actualLength; var currentX = (float)xstart; var currentY = (float)ystart; for( var pixel=0; pixel<actualLength; pixel++) { if (currentX > 0 && currentY > 0 && currentX < viewport.Width && currentY < viewport.Height) { var bufferOffset = (buffers.FrameBuffer.Stride*(int) currentY) + (int) currentX; buffers.FrameBuffer.Pixels[bufferOffset] = colorAsInt; } currentX += slopeX; currentY += slopeY; } } }
private static void RenderUnscaled(IBuffers buffer, int positionOffset, Image image, Vector translatedPosition, int bufferSize, UInt32 bufferZ) { var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var imageContext = image.ImageContext as ImageContext; var spriteOffset = 0; for (var y = 0; y < image.Height; y++) { var offset = y * buffer.FrameBuffer.Stride; var depthBufferOffset = (buffer.Width * ((int)translatedPosition.Y + y)) + (int)translatedPosition.X; for (var x = 0; x < image.Width; x++) { var actualOffset = offset + positionOffset; if (actualOffset >= 0 && actualOffset < bufferSize && bufferZ < buffer.DepthBuffer[depthBufferOffset]) { buffer.FrameBuffer.Pixels[actualOffset] = imageContext.Pixels[spriteOffset]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } offset ++; spriteOffset ++; depthBufferOffset++; } } }
private static void RenderUnscaled(IBuffers buffer, int positionOffset, Image image, Vector translatedPosition, int bufferSize, UInt32 bufferZ) { var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var imageContext = image.ImageContext as ImageContext; var spriteOffset = 0; for (var y = 0; y < image.Height; y++) { var offset = y * buffer.FrameBuffer.Stride; var depthBufferOffset = (buffer.Width * ((int)translatedPosition.Y + y)) + (int)translatedPosition.X; for (var x = 0; x < image.Width; x++) { var actualOffset = offset + positionOffset; if (actualOffset >= 0 && actualOffset < bufferSize && bufferZ < buffer.DepthBuffer[depthBufferOffset]) { buffer.FrameBuffer.Pixels[actualOffset] = imageContext.Pixels[spriteOffset]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } offset++; spriteOffset++; depthBufferOffset++; } } }
public Display() { BitmapMutex = new Mutex(); Bitmap = new Bitmap(640, 480, PixelFormat.Format32bppArgb); _lockRectangle = new Rectangle(0, 0, 640, 480); _buffers = BufferManager.Instance.Create<FrameBuffer>(640, 480); }
public Display() { BitmapMutex = new Mutex(); Bitmap = new Bitmap(640, 480, PixelFormat.Format32bppArgb); _lockRectangle = new Rectangle(0, 0, 640, 480); _buffers = BufferManager.Instance.Create <FrameBuffer>(640, 480); }
public void Texture(IBuffers buffer, Span span, Image image, ImageContext texture) { var spreadCount = span.XEnd - span.XStart; TextureInterpolator.SetPoint(0, span.ZStart, span.ZEnd); TextureInterpolator.SetPoint(1, span.UStart, span.UEnd); TextureInterpolator.SetPoint(2, span.VStart, span.VEnd); var yOffset = span.Y * buffer.FrameBuffer.Stride; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width * span.Y) + span.XStart; TextureInterpolator.Interpolate(spreadCount); var xOffset = span.XStart; for (var index = 0; index < spreadCount; index++) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = TextureInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32)(z * (float)UInt32.MaxValue); var u = TextureInterpolator.Points[1].InterpolatedValues[index]; var v = TextureInterpolator.Points[2].InterpolatedValues[index]; var intu = (int)(u * image.Width) & (image.Width - 1); var intv = (int)(v * image.Height) & (image.Height - 1); var texel = ((intv * image.Width) + intu); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.FrameBuffer.Pixels[bufferOffset] = texture.Pixels[texel]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } } bufferOffset++; depthBufferOffset++; xOffset++; } }
public void Gouraud(IBuffers buffer, Span span) { var spreadCount = span.XEnd - span.XStart; GouraudInterpolator.SetPoint(0, span.ZStart, span.ZEnd); GouraudInterpolator.SetPoint(1, span.ColorStart.Red, span.ColorEnd.Red); GouraudInterpolator.SetPoint(2, span.ColorStart.Green, span.ColorEnd.Green); GouraudInterpolator.SetPoint(3, span.ColorStart.Blue, span.ColorEnd.Blue); GouraudInterpolator.SetPoint(4, span.ColorStart.Alpha, span.ColorEnd.Alpha); var yOffset = buffer.FrameBuffer.Stride * span.Y; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width * span.Y) + span.XStart; GouraudInterpolator.Interpolate(spreadCount); var xOffset = span.XStart; for (var index = 0; index < spreadCount; index++) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = GouraudInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32)(z * (float)UInt32.MaxValue); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.DepthBuffer[depthBufferOffset] = bufferZ; ColorAsVector.Red = GouraudInterpolator.Points[1].InterpolatedValues[index]; ColorAsVector.Green = GouraudInterpolator.Points[2].InterpolatedValues[index]; ColorAsVector.Blue = GouraudInterpolator.Points[3].InterpolatedValues[index]; ColorAsVector.Alpha = GouraudInterpolator.Points[4].InterpolatedValues[index]; var color = (int)ColorAsVector.ToColor().ToUInt32(); buffer.FrameBuffer.Pixels[bufferOffset] = color; } } xOffset++; bufferOffset++; depthBufferOffset++; } }
private static void RenderScaled(IBuffers buffer, int positionOffset, Image image, Vector translatedPosition, int bufferSize, UInt32 bufferZ, float xScale, float yScale) { var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var imageContext = image.ImageContext as ImageContext; var actualWidth = (int)(((float)image.Width) * xScale); var actualHeight = (int)(((float)image.Height) * yScale); if (actualWidth <= 0 || actualHeight <= 0) { return; } var spriteOffset = 0; XScalingInterpolator.SetPoint(0, 0f, image.Width); XScalingInterpolator.Interpolate(actualWidth); YScalingInterpolator.SetPoint(0, 0f, image.Height); YScalingInterpolator.Interpolate(actualHeight); for (var y = 0; y < actualHeight; y++) { var offset = y * buffer.FrameBuffer.Stride; var depthBufferOffset = (buffer.Width * ((int)translatedPosition.Y + y)) + (int)translatedPosition.X; var spriteY = (int)YScalingInterpolator.Points[0].InterpolatedValues[y]; for (var x = 0; x < actualWidth; x++) { var actualOffset = offset + positionOffset; var spriteX = (int)XScalingInterpolator.Points[0].InterpolatedValues[x]; spriteOffset = (int)((spriteY * image.Width) + spriteX); if (actualOffset >= 0 && actualOffset < bufferSize && bufferZ < buffer.DepthBuffer[depthBufferOffset]) { buffer.FrameBuffer.Pixels[actualOffset] = imageContext.Pixels[spriteOffset]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } offset++; depthBufferOffset++; } } }
private static void RenderScaled(IBuffers buffer, int positionOffset, Image image, Vector translatedPosition, int bufferSize, UInt32 bufferZ, float xScale, float yScale) { var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var imageContext = image.ImageContext as ImageContext; var actualWidth = (int) (((float) image.Width)*xScale); var actualHeight = (int) (((float) image.Height)*yScale); if( actualWidth <= 0 || actualHeight <=0 ) { return; } var spriteOffset = 0; XScalingInterpolator.SetPoint(0,0f,image.Width); XScalingInterpolator.Interpolate(actualWidth); YScalingInterpolator.SetPoint(0,0f,image.Height); YScalingInterpolator.Interpolate(actualHeight); for (var y = 0; y < actualHeight; y++) { var offset = y*buffer.FrameBuffer.Stride; var depthBufferOffset = (buffer.Width*((int) translatedPosition.Y + y)) + (int) translatedPosition.X; var spriteY = (int)YScalingInterpolator.Points[0].InterpolatedValues[y]; for (var x = 0; x < actualWidth; x++) { var actualOffset = offset + positionOffset; var spriteX = (int)XScalingInterpolator.Points[0].InterpolatedValues[x]; spriteOffset = (int)((spriteY*image.Width) + spriteX); if (actualOffset >= 0 && actualOffset < bufferSize && bufferZ < buffer.DepthBuffer[depthBufferOffset]) { buffer.FrameBuffer.Pixels[actualOffset] = imageContext.Pixels[spriteOffset]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } offset ++; depthBufferOffset++; } } }
public void Gouraud(IBuffers buffer, Span span) { var spreadCount = span.XEnd - span.XStart; GouraudInterpolator.SetPoint(0, span.ZStart, span.ZEnd); GouraudInterpolator.SetPoint(1, span.ColorStart.Red, span.ColorEnd.Red); GouraudInterpolator.SetPoint(2, span.ColorStart.Green, span.ColorEnd.Green); GouraudInterpolator.SetPoint(3, span.ColorStart.Blue, span.ColorEnd.Blue); GouraudInterpolator.SetPoint(4, span.ColorStart.Alpha, span.ColorEnd.Alpha); var yOffset = buffer.FrameBuffer.Stride * span.Y; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width*span.Y)+span.XStart; GouraudInterpolator.Interpolate(spreadCount); var xOffset = span.XStart; for (var index = 0; index < spreadCount; index++) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = GouraudInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32) (z*(float) UInt32.MaxValue); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.DepthBuffer[depthBufferOffset] = bufferZ; ColorAsVector.Red = GouraudInterpolator.Points[1].InterpolatedValues[index]; ColorAsVector.Green = GouraudInterpolator.Points[2].InterpolatedValues[index]; ColorAsVector.Blue = GouraudInterpolator.Points[3].InterpolatedValues[index]; ColorAsVector.Alpha = GouraudInterpolator.Points[4].InterpolatedValues[index]; var color = (int)ColorAsVector.ToColor().ToUInt32(); buffer.FrameBuffer.Pixels[bufferOffset] = color; } } xOffset++; bufferOffset ++; depthBufferOffset++; } }
public void Flat(IBuffers buffer, Span span, Color color) { var spreadCount = span.Length; //span.XEnd - span.XStart; DepthInterpolator.SetPoint(0, span.ZStart, span.ZEnd); var yOffset = span.Y * buffer.FrameBuffer.Stride; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width * span.Y) + span.XStart; DepthInterpolator.Interpolate(spreadCount); var colorAsInt = (int)color.ToUInt32(); var xOffset = span.XStart; for (var index = 0; index < spreadCount; index++) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = DepthInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32)(z * (float)UInt32.MaxValue); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.FrameBuffer.Pixels[bufferOffset] = colorAsInt; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } else { int i = 0; i++; } } xOffset++; bufferOffset++; depthBufferOffset++; } }
public void Flat(IBuffers buffer, Span span, Color color) { var spreadCount = span.Length; //span.XEnd - span.XStart; DepthInterpolator.SetPoint(0, span.ZStart, span.ZEnd); var yOffset = span.Y*buffer.FrameBuffer.Stride; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width*span.Y) + span.XStart; DepthInterpolator.Interpolate(spreadCount); var colorAsInt = (int)color.ToUInt32(); var xOffset = span.XStart; for( var index=0; index<spreadCount; index++ ) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = DepthInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32) (z*(float) UInt32.MaxValue); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.FrameBuffer.Pixels[bufferOffset] = colorAsInt; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } else { int i = 0; i++; } } xOffset++; bufferOffset++; depthBufferOffset++; } }
private void Initialize() { AutomaticallyAdjustDimensions(); _image = new Image { Stretch = Stretch.None }; _buffers = BufferManager.Instance.Create <FrameBuffer>((int)Width, (int)Height); _image.Source = _buffers.FrameBuffer.BitmapSource; _buffers.FrameBuffer.Render += OnDraw; _buffers.FrameBuffer.Updated += OnUpdate; BufferManager.Instance.Current = _buffers; _buffers.Start(); _image.Width = Width; _image.Height = Height; Children.Add(_image); }
public static void Draw(IBuffers buffers, ISpanRenderer renderer, TriangleShade shade, Face face, Vertex[] vertices, TextureCoordinate[] textureCoordinates) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; var textureA = ZeroTextureCoordinate; var textureB = ZeroTextureCoordinate; var textureC = ZeroTextureCoordinate; Image image = null; ImageContext texture = null; var useTexture = false; if (null != face.Material && null != face.Material.DiffuseMap) { useTexture = true; image = face.Material.DiffuseMap; texture = face.Material.DiffuseMap.ImageContext as ImageContext; textureA = textureCoordinates[face.DiffuseA]; textureB = textureCoordinates[face.DiffuseB]; textureC = textureCoordinates[face.DiffuseC]; } /* * SetSphericalEnvironmentMapTextureCoordinate(ref vertexA, ref textureA); * SetSphericalEnvironmentMapTextureCoordinate(ref vertexB, ref textureB); * SetSphericalEnvironmentMapTextureCoordinate(ref vertexC, ref textureC); */ GetSortedPoints(ref vertexA, ref vertexB, ref vertexC, ref textureA, ref textureB, ref textureC); var interpolator = GetInterpolatorForFace(face, shade); var secondaryStartY = (int)(vertexB.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y); var spreadCount = ((int)(vertexC.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y)) + 1; interpolator.SetPoint(0, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X); interpolator.SetPoint(1, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X, secondaryStartY); interpolator.SetPoint(2, vertexA.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ); interpolator.SetPoint(3, vertexA.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ, secondaryStartY); if (useTexture) { interpolator.SetPoint(4, textureA.U, textureC.U); interpolator.SetPoint(5, textureA.U, textureB.U, textureB.U, textureC.U, secondaryStartY); interpolator.SetPoint(6, textureA.V, textureC.V); interpolator.SetPoint(7, textureA.V, textureB.V, textureB.V, textureC.V, secondaryStartY); } var color = Color.FromArgb(0xff, 0xff, 0xff, 0xff); if (shade == TriangleShade.Gouraud && !useTexture) { var vertexAColor = vertexA.Color.ToVector(); var vertexBColor = vertexB.Color.ToVector(); var vertexCColor = vertexC.Color.ToVector(); interpolator.SetPoint(4, vertexAColor.Red, vertexCColor.Red); interpolator.SetPoint(5, vertexAColor.Red, vertexBColor.Red, vertexBColor.Red, vertexCColor.Red, secondaryStartY); interpolator.SetPoint(6, vertexAColor.Green, vertexCColor.Green); interpolator.SetPoint(7, vertexAColor.Green, vertexBColor.Green, vertexBColor.Green, vertexCColor.Green, secondaryStartY); interpolator.SetPoint(8, vertexAColor.Blue, vertexCColor.Blue); interpolator.SetPoint(9, vertexAColor.Blue, vertexBColor.Blue, vertexBColor.Blue, vertexCColor.Blue, secondaryStartY); interpolator.SetPoint(10, vertexAColor.Alpha, vertexCColor.Alpha); interpolator.SetPoint(11, vertexAColor.Alpha, vertexBColor.Alpha, vertexBColor.Alpha, vertexCColor.Alpha, secondaryStartY); } else { color = face.Color; } interpolator.Interpolate(spreadCount); var yPosition = vertexA.TranslatedScreenCoordinates.Y; var clip = false; if (null == buffers) { return; } for (var index = 0; index < spreadCount; index++) { if (yPosition < 0 || yPosition >= buffers.Height) { clip = true; } else { clip = false; } var span = GetSpan(index, interpolator, vertexA, useTexture); if (null != span && !clip) { var actualSpan = (Span)span; var swapIndex = ((Span)span).Swap ? 1 : 0; actualSpan.ZStart = interpolator.Points[2 + swapIndex].InterpolatedValues[index]; actualSpan.ZEnd = interpolator.Points[3 - swapIndex].InterpolatedValues[index]; switch (shade) { case TriangleShade.Flat: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { renderer.Flat(buffers, actualSpan, color); } } break; case TriangleShade.Gouraud: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { actualSpan.ColorStart.Red = interpolator.Points[4 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Red = interpolator.Points[5 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Green = interpolator.Points[6 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Green = interpolator.Points[7 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Blue = interpolator.Points[8 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Blue = interpolator.Points[9 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.Alpha = interpolator.Points[10 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.Alpha = interpolator.Points[11 - swapIndex].InterpolatedValues[index]; renderer.Gouraud(buffers, actualSpan); } } break; } } yPosition++; } }
public static void Draw(IBuffers buffers, ISpanRenderer renderer, TriangleShade shade, Face face, Vertex[] vertices, TextureCoordinate[] textureCoordinates) { var vertexA = vertices[face.A]; var vertexB = vertices[face.B]; var vertexC = vertices[face.C]; var textureA = ZeroTextureCoordinate; var textureB = ZeroTextureCoordinate; var textureC = ZeroTextureCoordinate; Image image = null; ImageContext texture = null; var useTexture = false; if( null != face.Material && null != face.Material.DiffuseMap) { useTexture = true; image = face.Material.DiffuseMap; texture = face.Material.DiffuseMap.ImageContext as ImageContext; textureA = textureCoordinates[face.DiffuseA]; textureB = textureCoordinates[face.DiffuseB]; textureC = textureCoordinates[face.DiffuseC]; } /* SetSphericalEnvironmentMapTextureCoordinate(ref vertexA, ref textureA); SetSphericalEnvironmentMapTextureCoordinate(ref vertexB, ref textureB); SetSphericalEnvironmentMapTextureCoordinate(ref vertexC, ref textureC); */ GetSortedPoints(ref vertexA, ref vertexB, ref vertexC, ref textureA, ref textureB, ref textureC); var interpolator = GetInterpolatorForFace(face, shade); var secondaryStartY = (int)(vertexB.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y); var spreadCount = ((int)(vertexC.TranslatedScreenCoordinates.Y - vertexA.TranslatedScreenCoordinates.Y)) + 1; interpolator.SetPoint(0, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X); interpolator.SetPoint(1, (int)vertexA.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexB.TranslatedScreenCoordinates.X, (int)vertexC.TranslatedScreenCoordinates.X, secondaryStartY); interpolator.SetPoint(2, vertexA.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ); interpolator.SetPoint(3, vertexA.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexB.DepthBufferAdjustedZ, vertexC.DepthBufferAdjustedZ, secondaryStartY); if (useTexture) { interpolator.SetPoint(4, textureA.U, textureC.U); interpolator.SetPoint(5, textureA.U, textureB.U, textureB.U, textureC.U, secondaryStartY); interpolator.SetPoint(6, textureA.V, textureC.V); interpolator.SetPoint(7, textureA.V, textureB.V, textureB.V, textureC.V, secondaryStartY); } var color = Color.FromArgb(0xff, 0xff, 0xff, 0xff); if (shade == TriangleShade.Gouraud && !useTexture) { var vertexAColor = vertexA.Color; var vertexBColor = vertexB.Color; var vertexCColor = vertexC.Color; interpolator.SetPoint(4, vertexAColor.RedAsFloat, vertexCColor.RedAsFloat); interpolator.SetPoint(5, vertexAColor.RedAsFloat, vertexBColor.RedAsFloat, vertexBColor.RedAsFloat, vertexCColor.RedAsFloat, secondaryStartY); interpolator.SetPoint(6, vertexAColor.GreenAsFloat, vertexCColor.GreenAsFloat); interpolator.SetPoint(7, vertexAColor.GreenAsFloat, vertexBColor.GreenAsFloat, vertexBColor.GreenAsFloat, vertexCColor.GreenAsFloat, secondaryStartY); interpolator.SetPoint(8, vertexAColor.BlueAsFloat, vertexCColor.BlueAsFloat); interpolator.SetPoint(9, vertexAColor.BlueAsFloat, vertexBColor.BlueAsFloat, vertexBColor.BlueAsFloat, vertexCColor.BlueAsFloat, secondaryStartY); interpolator.SetPoint(10, vertexAColor.AlphaAsFloat, vertexCColor.AlphaAsFloat); interpolator.SetPoint(11, vertexAColor.AlphaAsFloat, vertexBColor.AlphaAsFloat, vertexBColor.AlphaAsFloat, vertexCColor.AlphaAsFloat, secondaryStartY); } else { color = face.Color; } interpolator.Interpolate(spreadCount); var yPosition = vertexA.TranslatedScreenCoordinates.Y; var clip = false; if( null == buffers ) { return; } for (var index = 0; index < spreadCount; index++) { if( yPosition < 0 || yPosition >= buffers.Height ) { clip = true; } else { clip = false; } var span = GetSpan(index, interpolator, vertexA, useTexture); if (null != span && !clip ) { var actualSpan = (Span)span; var swapIndex = ((Span)span).Swap ? 1 : 0; actualSpan.ZStart = interpolator.Points[2 + swapIndex].InterpolatedValues[index]; actualSpan.ZEnd = interpolator.Points[3 - swapIndex].InterpolatedValues[index]; switch (shade) { case TriangleShade.Flat: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { renderer.Flat(buffers, actualSpan, color); } } break; case TriangleShade.Gouraud: { if (useTexture) { renderer.Texture(buffers, actualSpan, image, texture); } else { actualSpan.ColorStart.RedAsFloat = interpolator.Points[4 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.RedAsFloat = interpolator.Points[5 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.GreenAsFloat = interpolator.Points[6 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.GreenAsFloat = interpolator.Points[7 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.BlueAsFloat = interpolator.Points[8 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.BlueAsFloat = interpolator.Points[9 - swapIndex].InterpolatedValues[index]; actualSpan.ColorStart.AlphaAsFloat = interpolator.Points[10 + swapIndex].InterpolatedValues[index]; actualSpan.ColorEnd.AlphaAsFloat = interpolator.Points[11 - swapIndex].InterpolatedValues[index]; renderer.Gouraud(buffers, actualSpan); } } break; } } yPosition++; } }
public void Texture(IBuffers buffer, Span span, Image image, ImageContext texture) { var spreadCount = span.XEnd - span.XStart; TextureInterpolator.SetPoint(0, span.ZStart, span.ZEnd); TextureInterpolator.SetPoint(1, span.UStart, span.UEnd); TextureInterpolator.SetPoint(2, span.VStart, span.VEnd); var yOffset = span.Y * buffer.FrameBuffer.Stride; var rOffset = buffer.FrameBuffer.RedPosition; var gOffset = buffer.FrameBuffer.GreenPosition; var bOffset = buffer.FrameBuffer.BluePosition; var aOffset = buffer.FrameBuffer.AlphaPosition; var bufferOffset = yOffset + span.XStart; var depthBufferOffset = (buffer.Width * span.Y) + span.XStart; TextureInterpolator.Interpolate(spreadCount); var xOffset = span.XStart; for (var index = 0; index < spreadCount; index++) { if (xOffset >= 0 && xOffset < buffer.Width) { var z = TextureInterpolator.Points[0].InterpolatedValues[index]; var bufferZ = (UInt32) (z*(float) UInt32.MaxValue); var u = TextureInterpolator.Points[1].InterpolatedValues[index]; var v = TextureInterpolator.Points[2].InterpolatedValues[index]; var intu = (int) (u*image.Width) & (image.Width - 1); var intv = (int) (v*image.Height) & (image.Height - 1); var texel = ((intv*image.Width) + intu); if (bufferZ < buffer.DepthBuffer[depthBufferOffset] && z >= 0f && z < 1f ) { buffer.FrameBuffer.Pixels[bufferOffset] = texture.Pixels[texel]; buffer.DepthBuffer[depthBufferOffset] = bufferZ; } } bufferOffset ++; depthBufferOffset++; xOffset++; } }