public static void DrawTriangle2(Model m, int i) { var centerX = SoftwareRasterizer3D.CenterX; var centerY = SoftwareRasterizer3D.CenterY; var j = 0; var a = m.TriangleViewspaceA[i]; var b = m.TriangleViewspaceB[i]; var c = m.TriangleViewspaceC[i]; var aZ = TmpTexturedZ[a]; var bZ = TmpTexturedZ[b]; var cZ = TmpTexturedZ[c]; if (aZ >= 50) { TmpScreenX[j] = TriangleX[a]; TmpScreenY[j] = TriangleY[a]; TmpHsl[j++] = m.TriHsl1[i]; } else { int x = TmpTexturedX[a]; int y = TmpTexturedY[a]; int hsl = m.TriHsl1[i]; if (cZ >= 50) { int decay = (50 - aZ) * SoftwareRasterizer3D.ShadowDecay[cZ - aZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[c] - x) * decay >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[c] - y) * decay >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl3[i] - hsl) * decay >> 16); } if (bZ >= 50) { int decay = (50 - aZ) * SoftwareRasterizer3D.ShadowDecay[bZ - aZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[b] - x) * decay >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[b] - y) * decay >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl2[i] - hsl) * decay >> 16); } } if (bZ >= 50) { TmpScreenX[j] = TriangleX[b]; TmpScreenY[j] = TriangleY[b]; TmpHsl[j++] = m.TriHsl2[i]; } else { int x = TmpTexturedX[b]; int y = TmpTexturedY[b]; int hsl = m.TriHsl2[i]; if (aZ >= 50) { int i6 = (50 - bZ) * SoftwareRasterizer3D.ShadowDecay[aZ - bZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[a] - x) * i6 >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[a] - y) * i6 >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl1[i] - hsl) * i6 >> 16); } if (cZ >= 50) { int j6 = (50 - bZ) * SoftwareRasterizer3D.ShadowDecay[cZ - bZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[c] - x) * j6 >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[c] - y) * j6 >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl3[i] - hsl) * j6 >> 16); } } if (cZ >= 50) { TmpScreenX[j] = TriangleX[c]; TmpScreenY[j] = TriangleY[c]; TmpHsl[j++] = m.TriHsl3[i]; } else { var x = TmpTexturedX[c]; var y = TmpTexturedY[c]; var hsl = m.TriHsl3[i]; if (bZ >= 50) { var k6 = (50 - cZ) * SoftwareRasterizer3D.ShadowDecay[bZ - cZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[b] - x) * k6 >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[b] - y) * k6 >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl2[i] - hsl) * k6 >> 16); } if (aZ >= 50) { var l6 = (50 - cZ) * SoftwareRasterizer3D.ShadowDecay[aZ - cZ]; TmpScreenX[j] = centerX + (x + ((TmpTexturedX[a] - x) * l6 >> 16) << 9) / 50; TmpScreenY[j] = centerY + (y + ((TmpTexturedY[a] - y) * l6 >> 16) << 9) / 50; TmpHsl[j++] = hsl + ((m.TriHsl2[i] - hsl) * l6 >> 16); } } var x0 = TmpScreenX[0]; var x1 = TmpScreenX[1]; var x2 = TmpScreenX[2]; var y0 = TmpScreenY[0]; var y1 = TmpScreenY[1]; var y2 = TmpScreenY[2]; if ((x0 - x1) * (y2 - y1) - (y0 - y1) * (x2 - x1) > 0) { SoftwareRasterizer3D.CheckBounds = false; if (j == 3) { if (x0 < 0 || x1 < 0 || x2 < 0 || x0 > SoftwareRasterizer2D.Bound || x1 > SoftwareRasterizer2D.Bound || x2 > SoftwareRasterizer2D.Bound) { SoftwareRasterizer3D.CheckBounds = true; } var type = 0; if (m.TriangleInfo != null) { type = m.TriangleInfo[i] & 3; } if (type == TypeShadedTri) { SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); } else if (type == TypeFlatTri) { SoftwareRasterizer3D.DrawFlatTriangle(x0, y0, x1, y1, x2, y2, ColorUtils.HSLToRGBMap[m.TriHsl1[i]]); } else if (type == TypeShadedTexTri) { var k = m.TriangleInfo[i] >> 2; var x = m.TextureMapX[k]; var y = m.TextureMapY[k]; var z = m.TextureMapZ[k]; SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); } else if (type == TypeFlatTexTri) { var k = m.TriangleInfo[i] >> 2; var x = m.TextureMapX[k]; var y = m.TextureMapY[k]; var z = m.TextureMapZ[k]; SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); } } else if (j == 4) { if (x0 < 0 || x1 < 0 || x2 < 0 || x0 > SoftwareRasterizer2D.Bound || x1 > SoftwareRasterizer2D.Bound || x2 > SoftwareRasterizer2D.Bound || TmpScreenX[3] < 0 || TmpScreenX[3] > SoftwareRasterizer2D.Bound) { SoftwareRasterizer3D.CheckBounds = true; } var type = 0; if (m.TriangleInfo != null) { type = m.TriangleInfo[i] & 3; } if (type == TypeShadedTri) { SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x2, y2, TmpScreenX[3], TmpScreenY[3], TmpHsl[0], TmpHsl[2], TmpHsl[3]); } else if (type == TypeFlatTri) { var rgb = ColorUtils.HSLToRGBMap[m.TriHsl1[i]]; SoftwareRasterizer3D.DrawFlatTriangle(x0, y0, x1, y1, x2, y2, rgb); SoftwareRasterizer3D.DrawFlatTriangle(x0, y0, x2, y2, TmpScreenX[3], TmpScreenY[3], rgb); } else if (type == TypeShadedTexTri) { var k = m.TriangleInfo[i] >> 2; var x = m.TextureMapX[k]; var y = m.TextureMapY[k]; var z = m.TextureMapZ[k]; SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x2, y2, TmpScreenX[3], TmpScreenY[3], TmpHsl[0], TmpHsl[2], TmpHsl[3]); } else if (type == TypeFlatTexTri) { var k = m.TriangleInfo[i] >> 2; var x = m.TextureMapX[k]; var y = m.TextureMapY[k]; var z = m.TextureMapZ[k]; SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x1, y1, x2, y2, TmpHsl[0], TmpHsl[1], TmpHsl[2]); SoftwareRasterizer3D.DrawShadedTriangle(x0, y0, x2, y2, TmpScreenX[3], TmpScreenY[3], TmpHsl[0], TmpHsl[2], TmpHsl[3]); } } } }
public static void DrawTriangle(Model m, int idx) { if (TriangleProject[idx]) { DrawTriangle2(m, idx); return; } var firstTriVertex = m.TriangleViewspaceA[idx]; var secondTriVertex = m.TriangleViewspaceB[idx]; var thirdTriVertex = m.TriangleViewspaceC[idx]; SoftwareRasterizer3D.CheckBounds = TriangleCheckBounds[idx]; if (m.TriangleAlpha == null) { SoftwareRasterizer3D.Opacity = 0; } else { SoftwareRasterizer3D.Opacity = m.TriangleAlpha[idx]; } var type = 0; if (m.TriangleInfo != null) { type = m.TriangleInfo[idx] & 3; } switch (type) { case TypeShadedTri: { SoftwareRasterizer3D.DrawShadedTriangle(TriangleX[firstTriVertex], TriangleY[firstTriVertex], TriangleX[secondTriVertex], TriangleY[secondTriVertex], TriangleX[thirdTriVertex], TriangleY[thirdTriVertex], m.TriHsl1[idx], m.TriHsl2[idx], m.TriHsl3[idx]); return; } case TypeFlatTri: { SoftwareRasterizer3D.DrawFlatTriangle(TriangleX[firstTriVertex], TriangleY[firstTriVertex], TriangleX[secondTriVertex], TriangleY[secondTriVertex], TriangleX[thirdTriVertex], TriangleY[thirdTriVertex], ColorUtils.HSLToRGBMap[m.TriHsl1[idx]]); return; } case TypeShadedTexTri: { var j = m.TriangleInfo[idx] >> 2; var x = m.TextureMapX[j]; var y = m.TextureMapY[j]; var z = m.TextureMapZ[j]; SoftwareRasterizer3D.DrawShadedTriangle(TriangleX[firstTriVertex], TriangleY[firstTriVertex], TriangleX[secondTriVertex], TriangleY[secondTriVertex], TriangleX[thirdTriVertex], TriangleY[thirdTriVertex], m.TriHsl1[idx], m.TriHsl2[idx], m.TriHsl3[idx]); return; } case TypeFlatTexTri: { var j = m.TriangleInfo[idx] >> 2; var x = m.TextureMapX[j]; var y = m.TextureMapY[j]; var z = m.TextureMapZ[j]; SoftwareRasterizer3D.DrawShadedTriangle(TriangleX[firstTriVertex], TriangleY[firstTriVertex], TriangleX[secondTriVertex], TriangleY[secondTriVertex], TriangleX[thirdTriVertex], TriangleY[thirdTriVertex], m.TriHsl1[idx], m.TriHsl2[idx], m.TriHsl3[idx]); return; } } }