The perspective renderer is working better.

This commit is contained in:
larsbrubaker 2015-05-06 08:11:05 -07:00
parent ee8be322da
commit 939bafa214
2 changed files with 147 additions and 5 deletions

View file

@ -426,9 +426,16 @@ namespace MatterHackers.MatterControl
foreach (MeshGroup meshGroup in loadedMeshGroups)
{
double minZ = double.MaxValue;
double maxZ = double.MinValue;
foreach (Mesh loadedMesh in meshGroup.Meshes)
{
tracer.DrawTo(bigRender.NewGraphics2D(), loadedMesh, RGBA_Bytes.White);
tracer.GetMinMaxZ(loadedMesh, ref minZ, ref maxZ);
}
foreach (Mesh loadedMesh in meshGroup.Meshes)
{
tracer.DrawTo(bigRender.NewGraphics2D(), loadedMesh, RGBA_Bytes.White, minZ, maxZ);
}
}

View file

@ -119,13 +119,15 @@ namespace MatterHackers.RayTracer
static RGBA_Floats lightIllumination = new RGBA_Floats(1, 1, 1);
static RGBA_Floats ambiantIllumination = new RGBA_Floats(.4, .4, .4);
public void DrawTo(Graphics2D graphics2D, Mesh meshToDraw, RGBA_Bytes partColorIn)
public void DrawTo(Graphics2D graphics2D, Mesh meshToDraw, RGBA_Bytes partColorIn, double minZ, double maxZ)
{
RGBA_Floats partColor = partColorIn.GetAsRGBA_Floats();
graphics2D.Rasterizer.gamma(new gamma_power(.3));
PathStorage polygonProjected = new PathStorage();
foreach (Face face in meshToDraw.Faces)
{
double averageZ = 0;
Vector3 normal = Vector3.TransformVector(face.normal, trackballTumbleWidget.ModelviewMatrix).GetNormal();
if (normal.z > 0)
{
@ -143,8 +145,13 @@ namespace MatterHackers.RayTracer
{
polygonProjected.LineTo(screenPosition.x, screenPosition.y);
}
Vector3 transsformedPosition = Vector3.TransformPosition(faceEdge.firstVertex.Position, trackballTumbleWidget.ModelviewMatrix);
averageZ += transsformedPosition.z;
}
averageZ /= 3;
RGBA_Floats polyDrawColor = new RGBA_Floats();
double L = Vector3.Dot(lightNormal, normal);
if (L > 0.0f)
@ -153,14 +160,133 @@ namespace MatterHackers.RayTracer
}
polyDrawColor = RGBA_Floats.ComponentMax(polyDrawColor, partColor * ambiantIllumination);
double ratio = (averageZ - minZ) / (maxZ - minZ);
int ratioInt16 = (int)(ratio * 65536);
polyDrawColor.Alpha0To1 = 1;
graphics2D.Render(polygonProjected, polyDrawColor.GetAsRGBA_Bytes());
//RGBA_Bytes renderColor = new RGBA_Bytes(polyDrawColor.Red0To255, ratioInt16 >> 8, ratioInt16 & 256);
RGBA_Bytes renderColor = new RGBA_Bytes(ratioInt16 >> 8, ratioInt16 >> 8, ratioInt16 >> 8);
//IRecieveBlenderByte oldBlender = graphics2D.DestImage.GetRecieveBlender();
//graphics2D.DestImage.SetRecieveBlender(new BlenderZBuffer());
graphics2D.Render(polygonProjected, renderColor);
//graphics2D.DestImage.SetRecieveBlender(oldBlender);
byte[] buffer = graphics2D.DestImage.GetBuffer();
int pixels = graphics2D.DestImage.Width * graphics2D.DestImage.Height;
for (int i = 0; i < pixels; i++)
{
//buffer[i * 4 + 0] = buffer[i * 4 + 2];
//buffer[i * 4 + 1] = buffer[i * 4 + 2];
}
}
}
graphics2D.Rasterizer.gamma(new gamma_none());
}
public sealed class BlenderZBuffer : BlenderBase8888, IRecieveBlenderByte
{
public RGBA_Bytes PixelToColorRGBA_Bytes(byte[] buffer, int bufferOffset)
{
return new RGBA_Bytes(buffer[bufferOffset + ImageBuffer.OrderR], buffer[bufferOffset + ImageBuffer.OrderG], buffer[bufferOffset + ImageBuffer.OrderB], buffer[bufferOffset + ImageBuffer.OrderA]);
}
public void CopyPixels(byte[] buffer, int bufferOffset, RGBA_Bytes sourceColor, int count)
{
do
{
if (sourceColor.green > buffer[bufferOffset + ImageBuffer.OrderG])
{
buffer[bufferOffset + ImageBuffer.OrderR] = sourceColor.red;
buffer[bufferOffset + ImageBuffer.OrderG] = sourceColor.green;
buffer[bufferOffset + ImageBuffer.OrderB] = sourceColor.blue;
buffer[bufferOffset + ImageBuffer.OrderA] = sourceColor.alpha;
}
bufferOffset += 4;
}
while (--count != 0);
}
public void BlendPixel(byte[] buffer, int bufferOffset, RGBA_Bytes sourceColor)
{
//unsafe
{
unchecked
{
if (sourceColor.alpha == 255)
{
buffer[bufferOffset + ImageBuffer.OrderR] = (byte)(sourceColor.red);
buffer[bufferOffset + ImageBuffer.OrderG] = (byte)(sourceColor.green);
buffer[bufferOffset + ImageBuffer.OrderB] = (byte)(sourceColor.blue);
buffer[bufferOffset + ImageBuffer.OrderA] = (byte)(sourceColor.alpha);
}
else
{
int r = buffer[bufferOffset + ImageBuffer.OrderR];
int g = buffer[bufferOffset + ImageBuffer.OrderG];
int b = buffer[bufferOffset + ImageBuffer.OrderB];
int a = buffer[bufferOffset + ImageBuffer.OrderA];
if (sourceColor.green > g)
{
buffer[bufferOffset + ImageBuffer.OrderR] = (byte)(((sourceColor.red - r) * sourceColor.alpha + (r << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift);
buffer[bufferOffset + ImageBuffer.OrderG] = (byte)(((sourceColor.green - g) * sourceColor.alpha + (g << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift);
buffer[bufferOffset + ImageBuffer.OrderB] = (byte)(((sourceColor.blue - b) * sourceColor.alpha + (b << (int)RGBA_Bytes.base_shift)) >> (int)RGBA_Bytes.base_shift);
buffer[bufferOffset + ImageBuffer.OrderA] = (byte)((sourceColor.alpha + a) - ((sourceColor.alpha * a + base_mask) >> (int)RGBA_Bytes.base_shift));
}
}
}
}
}
public void BlendPixels(byte[] destBuffer, int bufferOffset,
RGBA_Bytes[] sourceColors, int sourceColorsOffset,
byte[] covers, int coversIndex, bool firstCoverForAll, int count)
{
if (firstCoverForAll)
{
int cover = covers[coversIndex];
if (cover == 255)
{
do
{
BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset++]);
bufferOffset += 4;
}
while (--count != 0);
}
else
{
do
{
sourceColors[sourceColorsOffset].alpha = (byte)((sourceColors[sourceColorsOffset].alpha * cover + 255) >> 8);
BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset]);
bufferOffset += 4;
++sourceColorsOffset;
}
while (--count != 0);
}
}
else
{
do
{
int cover = covers[coversIndex++];
if (cover == 255)
{
BlendPixel(destBuffer, bufferOffset, sourceColors[sourceColorsOffset]);
}
else
{
RGBA_Bytes color = sourceColors[sourceColorsOffset];
color.alpha = (byte)((color.alpha * (cover) + 255) >> 8);
BlendPixel(destBuffer, bufferOffset, color);
}
bufferOffset += 4;
++sourceColorsOffset;
}
while (--count != 0);
}
}
}
AxisAlignedBoundingBox GetAxisAlignedBoundingBox(List<MeshGroup> meshGroups)
{
AxisAlignedBoundingBox totalMeshBounds = new AxisAlignedBoundingBox(Vector3.NegativeInfinity, Vector3.NegativeInfinity);
@ -182,6 +308,7 @@ namespace MatterHackers.RayTracer
return totalMeshBounds;
}
private void AddTestMesh(List<MeshGroup> meshGroups)
{
if (meshGroups != null)
@ -241,6 +368,14 @@ namespace MatterHackers.RayTracer
return screenBounds;
}
public void GetMinMaxZ(Mesh mesh, ref double minZ, ref double maxZ)
{
AxisAlignedBoundingBox meshBounds = mesh.GetAxisAlignedBoundingBox(trackballTumbleWidget.ModelviewMatrix);
minZ = Math.Min(meshBounds.minXYZ.z, minZ);
maxZ = Math.Max(meshBounds.maxXYZ.z, maxZ);
}
private bool NeedsToBeSmaller(RectangleDouble partScreenBounds, RectangleDouble goalBounds)
{
if (partScreenBounds.Bottom < goalBounds.Bottom