Gefüllte Triangles, Shaded Triangle von tasky |
Hi, hier ist ein von mir entwickelter Algorithmus, um gefüllte Dreiecke bzw. Dreiecke mit Farbübergängen zwischen den Eckpunkten zu zeichnen. Der Code ist ziemlich gross, was aber wiederum Geschwindigkeitsschub bedeutet. [b:f5e6cd2e05]Aufruf:[/b:f5e6cd2e05] Triangle(x0, y0, x1, y1, x2, y2, rgb, [buffer]) ShadedTriangle(x0, y0, x1, y1, x2, y2, r0, g0, b0, r1, g1, b1, r2, g2, b2, [buffer]) Beide Routinen arbeiten mit einem eigenen ViewPort der mit InitTriangle() initialisiert wird und mit TriangleViewPort(wLeft, wTop, wRight, wBottom) verändert werden kann. Wichtig ist, dass vor einem Aufruf (Triangle oder ShadedTriangle) [b:f5e6cd2e05]LockBuffer[/b:f5e6cd2e05] bzw. nach diesem [b:f5e6cd2e05]UnlockBuffer[/b:f5e6cd2e05] aufgerufen wird! [code:1:f5e6cd2e05] Global winLeft Global winRight Global winTop Global winBottom Graphics 1024, 768, 32, 1 SetBuffer BackBuffer() InitTriangle() While Not KeyHit(1) Cls a# = a# + .1 x0 = 512 + Sin(a) * 300 y0 = 384 + Cos(a) * 300 x1 = 512 + Sin(a + 120) * 300 y1 = 384 + Cos(a + 120) * 300 x2 = 512 + Sin(a + 240) * 300 y2 = 384 + Cos(a + 240) * 300 LockBuffer ShadedTriangle(x0, y0, x1, y1, x2, y2, 255, 0, 0, 0, 255, 0, 0, 0, 255) UnlockBuffer Flip Wend Function InitTriangle() winLeft = 0 winTop = 0 winRight = GraphicsWidth() - 1 winBottom = GraphicsHeight() - 1 End Function Function TriangleViewPort(wLeft, wTop, wRight, wBottom) winLeft = wLeft winTop = wTop winRight = wRight winBottom = wBottom End Function Function Triangle(x0, y0, x1, y1, x2, y2, rgb, buffer = 0) Local xc1, xp1, xp, dx1, dy1, df1, dm1, mc1, xs1 Local xc2, xp2, yp, dx2, dy2, df2, dm2, mc2, xs2 Local ey If buffer = 0 buffer = GraphicsBuffer() If y0 > y1 tmp = y0 y0 = y1 y1 = tmp tmp = x0 x0 = x1 x1 = tmp End If If y0 > y2 tmp = y0 y0 = y2 y2 = tmp tmp = x0 x0 = x2 x2 = tmp End If If y1 > y2 tmp = y1 y1 = y2 y2 = tmp tmp = x1 x1 = x2 x2 = tmp End If If y0 <> y1 If y1 = y2 ey = y1 Else ey = y1 - 1 End If dx1 = x1 - x0 dy1 = y1 - y0 df1 = dx1 / dy1 dm1 = Abs(dx1 Mod dy1) If x0 > x1 xs1 = -1 Else xs1 = 1 End If dx2 = x2 - x0 dy2 = y2 - y0 df2 = dx2 / dy2 dm2 = Abs(dx2 Mod dy2) If x0 > x2 xs2 = -1 Else xs2 = 1 End If xp1 = x0 mc1 = dm1 xp2 = x0 mc2 = dm2 For yp = y0 To ey xc1 = xp1 xc2 = xp2 If xc1 <> xc2 If yp >= winTop If yp <= winBottom If xc1 > xc2 tmp = xc1 xc1 = xc2 xc2 = tmp End If If xc1 <= winRight If xc2 >= winLeft If xc1 < winLeft xc1 = winLeft If xc2 > winRight xc2 = winRight For xp = xc1 To xc2 WritePixelFast xp, yp, rgb, buffer Next End If End If End If End If End If xp1 = xp1 + df1 mc1 = mc1 + dm1 If mc1 >= dy1 mc1 = mc1 - dy1 xp1 = xp1 + xs1 End If xp2 = xp2 + df2 mc2 = mc2 + dm2 If mc2 >= dy2 mc2 = mc2 - dy2 xp2 = xp2 + xs2 End If Next Else If y1 = y2 Return dx2 = x2 - x0 dy2 = y2 - y0 df2 = dx2 / dy2 dm2 = Abs(dx2 Mod dy2) If x0 > x2 xs2 = -1 Else xs2 = 1 End If xp2 = x0 mc2 = dm2 End If If y1 <> y2 dx1 = x2 - x1 dy1 = y2 - y1 df1 = dx1 / dy1 dm1 = Abs(dx1 Mod dy1) If x1 > x2 xs1 = -1 Else xs1 = 1 End If xp1 = x1 mc1 = dm1 If y2 > winBottom y2 = winBottom For yp = y1 To y2 xc1 = xp1 xc2 = xp2 If xc1 <> xc2 If yp >= winTop If yp <= winBottom If xc1 > xc2 tmp = xc1 xc1 = xc2 xc2 = tmp End If If xc1 <= winRight If xc2 >= winLeft If xc1 < winLeft xc1 = winLeft If xc2 > winRight xc2 = winRight For xp = xc1 To xc2 WritePixelFast xp, yp, rgb, buffer Next End If End If End If End If End If xp1 = xp1 + df1 mc1 = mc1 + dm1 If mc1 >= dy1 mc1 = mc1 - dy1 xp1 = xp1 + xs1 End If xp2 = xp2 + df2 mc2 = mc2 + dm2 If mc2 >= dy2 mc2 = mc2 - dy2 xp2 = xp2 + xs2 End If Next End If End Function Function ShadedTriangle(x0, y0, x1, y1, x2, y2, r0, g0, b0, r1, g1, b1, r2, g2, b2, buffer = 0) Local xc1, xp1, xp, dx1, dy1, df1, dm1, mc1, xs1 Local xc2, xp2, yp, dx2, dy2, df2, dm2, mc2, xs2 Local rcg1, rg1, dfrg1, mcrg1, dmrg1, rsg1, drg1, rg2, dfrg2, mcrg2, dmrg2, rcg2, rsg2, drg2 Local gcg1, gg1, dfgg1, mcgg1, dmgg1, gsg1, dgg1, gg2, dfgg2, mcgg2, dmgg2, gcg2, gsg2, dgg2 Local bcg1, bg1, dfbg1, mcbg1, dmbg1, bsg1, dbg1, bg2, dfbg2, mcbg2, dmbg2, bcg2, bsg2, dbg2 Local d, r, dfr, mcr, dmr, rs, dr, g, dfg, mcg, dmg, gs, dg, b, dfb, mcb, dmb, bs, db Local ey If buffer = 0 buffer = GraphicsBuffer() If y0 > y1 tmp = y0 y0 = y1 y1 = tmp tmp = x0 x0 = x1 x1 = tmp tmp = r0 r0 = r1 r1 = tmp tmp = g0 g0 = g1 g1 = tmp tmp = b0 b0 = b1 b1 = tmp End If If y0 > y2 tmp = y0 y0 = y2 y2 = tmp tmp = x0 x0 = x2 x2 = tmp tmp = r0 r0 = r2 r2 = tmp tmp = g0 g0 = g2 g2 = tmp tmp = b0 b0 = b2 b2 = tmp End If If y1 > y2 tmp = y1 y1 = y2 y2 = tmp tmp = x1 x1 = x2 x2 = tmp tmp = r1 r1 = r2 r2 = tmp tmp = g1 g1 = g2 g2 = tmp tmp = b1 b1 = b2 b2 = tmp End If If y0 <> y1 If y1 = y2 ey = y1 Else ey = y1 - 1 End If dx1 = x1 - x0 dy1 = y1 - y0 df1 = dx1 / dy1 dm1 = Abs(dx1 Mod dy1) dx2 = x2 - x0 dy2 = y2 - y0 df2 = dx2 / dy2 dm2 = Abs(dx2 Mod dy2) drg1 = r1 - r0 dfrg1 = drg1 / dy1 dmrg1 = Abs(drg1 Mod dy1) dgg1 = g1 - g0 dfgg1 = dgg1 / dy1 dmgg1 = Abs(dgg1 Mod dy1) dbg1 = b1 - b0 dfbg1 = dbg1 / dy1 dmbg1 = Abs(dbg1 Mod dy1) drg2 = r2 - r0 dfrg2 = drg2 / dy2 dmrg2 = Abs(drg2 Mod dy2) dgg2 = g2 - g0 dfgg2 = dgg2 / dy2 dmgg2 = Abs(dgg2 Mod dy2) dbg2 = b2 - b0 dfbg2 = dbg2 / dy2 dmbg2 = Abs(dbg2 Mod dy2) If x0 > x2 xs2 = -1 Else xs2 = 1 End If If x0 > x1 xs1 = -1 Else xs1 = 1 End If If r0 > r1 rsg1 = -1 Else rsg1 = 1 End If If g0 > g1 gsg1 = -1 Else gsg1 = 1 End If If b0 > b1 bsg1 = -1 Else bsg1 = 1 End If If r0 > r2 rsg2 = -1 Else rsg2 = 1 End If If g0 > g2 gsg2 = -1 Else gsg2 = 1 End If If b0 > b2 bsg2 = -1 Else bsg2 = 1 End If xp1 = x0 mc1 = dm1 xp2 = x0 mc2 = dm2 rg1 = r0 mcrg1 = dmrg1 gg1 = g0 mcgg1 = dmgg1 bg1 = b0 mcbg1 = dmbg1 rg2 = r0 mcrg2 = dmrg2 gg2 = g0 mcgg2 = dmgg2 bg2 = b0 mcbg2 = dmbg2 For yp = y0 To ey xc1 = xp1 xc2 = xp2 rcg1 = rg1 gcg1 = gg1 bcg1 = bg1 rcg2 = rg2 gcg2 = gg2 bcg2 = bg2 If xc1 <> xc2 If yp >= winTop If yp <= winBottom If xc1 > xc2 tmp = xc1 xc1 = xc2 xc2 = tmp tmp = rcg1 rcg1 = rcg2 rcg2 = tmp tmp = gcg1 gcg1 = gcg2 gcg2 = tmp tmp = bcg1 bcg1 = bcg2 bcg2 = tmp End If If xc1 <= winRight If xc2 >= winLeft d = xc2 - xc1 If xc1 < winLeft xc1 = winLeft If xc2 > winRight xc2 = winRight If rcg1 > rcg2 rs = -1 Else rs = 1 End If If gcg1 > gcg2 gs = -1 Else gs = 1 End If If bcg1 > bcg2 bs = -1 Else bs = 1 End If dr = rcg2 - rcg1 dfr = dr / d dmr = Abs(dr Mod d) dg = gcg2 - gcg1 dfg = dg / d dmg = Abs(dg Mod d) db = bcg2 - bcg1 dfb = db / d dmb = Abs(db Mod d) r = rcg1 mcr = dmr g = gcg1 mcg = dmg b = bcg1 mcb = dmb For xp = xc1 To xc2 WritePixelFast xp, yp, (r Shl 16) Or (g Shl 8) Or b, buffer r = r + dfr g = g + dfg b = b + dfb mcr = mcr + dmr If mcr >= d mcr = mcr - d r = r + rs End If mcg = mcg + dmg If mcg >= d mcg = mcg - d g = g + gs End If mcb = mcb + dmb If mcb >= d mcb = mcb - d b = b + bs End If Next End If End If End If End If End If xp1 = xp1 + df1 xp2 = xp2 + df2 rg1 = rg1 + dfrg1 gg1 = gg1 + dfgg1 bg1 = bg1 + dfbg1 rg2 = rg2 + dfrg2 gg2 = gg2 + dfgg2 bg2 = bg2 + dfbg2 mc1 = mc1 + dm1 mc2 = mc2 + dm2 mcrg1 = mcrg1 + dmrg1 mcgg1 = mcgg1 + dmgg1 mcbg1 = mcbg1 + dmbg1 mcrg2 = mcrg2 + dmrg2 mcgg2 = mcgg2 + dmgg2 mcbg2 = mcbg2 + dmbg2 If mc1 >= dy1 mc1 = mc1 - dy1 xp1 = xp1 + xs1 End If If mc2 >= dy2 mc2 = mc2 - dy2 xp2 = xp2 + xs2 End If If mcrg1 >= dy1 mcrg1 = mcrg1 - dy1 rg1 = rg1 + rsg1 End If If mcgg1 >= dy1 mcgg1 = mcgg1 - dy1 gg1 = gg1 + gsg1 End If If mcbg1 >= dy1 mcbg1 = mcbg1 - dy1 bg1 = bg1 + bsg1 End If If mcrg2 >= dy2 mcrg2 = mcrg2 - dy2 rg2 = rg2 + rsg2 End If If mcgg2 >= dy2 mcgg2 = mcgg2 - dy2 gg2 = gg2 + gsg2 End If If mcbg2 >= dy2 mcbg2 = mcbg2 - dy2 bg2 = bg2 + bsg2 End If Next Else If y1 = y2 Return dx2 = x2 - x0 dy2 = y2 - y0 df2 = dx2 / dy2 dm2 = Abs(dx2 Mod dy2) drg2 = r2 - r0 dfrg2 = drg2 / dy2 dmrg2 = Abs(drg2 Mod dy2) dgg2 = g2 - g0 dfgg2 = dgg2 / dy2 dmgg2 = Abs(dgg2 Mod dy2) dbg2 = b2 - b0 dfbg2 = dbg2 / dy2 dmbg2 = Abs(dbg2 Mod dy2) If x0 > x2 xs2 = -1 Else xs2 = 1 End If If r0 > r2 rsg2 = -1 Else rsg2 = 1 End If If g0 > g2 gsg2 = -1 Else gsg2 = 1 End If If b0 > b2 bsg2 = -1 Else bsg2 = 1 End If xp2 = x0 mc2 = dm2 rg2 = r0 mcrg2 = dmrg2 gg2 = g0 mcgg2 = dmgg2 bg2 = b0 mcbg2 = dmbg2 End If If y1 <> y2 dx1 = x2 - x1 dy1 = y2 - y1 df1 = dx1 / dy1 dm1 = Abs(dx1 Mod dy1) drg1 = r2 - r1 dfrg1 = drg1 / dy1 dmrg1 = Abs(drg1 Mod dy1) dgg1 = g2 - g1 dfgg1 = dgg1 / dy1 dmgg1 = Abs(dgg1 Mod dy1) dbg1 = b2 - b1 dfbg1 = dbg1 / dy1 dmbg1 = Abs(dbg1 Mod dy1) If x1 > x2 xs1 = -1 Else xs1 = 1 End If If r1 > r2 rsg1 = -1 Else rsg1 = 1 End If If g1 > g2 gsg1 = -1 Else gsg1 = 1 End If If b1 > b2 bsg1 = -1 Else bsg1 = 1 End If xp1 = x1 mc1 = dm1 rg1 = r1 mcrg1 = dmrg1 gg1 = g1 mcgg1 = dmgg1 bg1 = b1 mcbg1 = dmbg1 If y2 > winBottom y2 = winBottom For yp = y1 To y2 xc1 = xp1 xc2 = xp2 rcg1 = rg1 gcg1 = gg1 bcg1 = bg1 rcg2 = rg2 gcg2 = gg2 bcg2 = bg2 If xc1 <> xc2 If yp >= winTop If yp <= winBottom If xc1 > xc2 tmp = xc1 xc1 = xc2 xc2 = tmp tmp = rcg1 rcg1 = rcg2 rcg2 = tmp tmp = gcg1 gcg1 = gcg2 gcg2 = tmp tmp = bcg1 bcg1 = bcg2 bcg2 = tmp End If If xc1 <= winRight If xc2 >= winLeft d = xc2 - xc1 If xc1 < winLeft xc1 = winLeft If xc2 > winRight xc2 = winRight If rcg1 > rcg2 rs = -1 Else rs = 1 End If If gcg1 > gcg2 gs = -1 Else gs = 1 End If If bcg1 > bcg2 bs = -1 Else bs = 1 End If dr = rcg2 - rcg1 dfr = dr / d dmr = Abs(dr Mod d) dg = gcg2 - gcg1 dfg = dg / d dmg = Abs(dg Mod d) db = bcg2 - bcg1 dfb = db / d dmb = Abs(db Mod d) r = rcg1 mcr = dmr g = gcg1 mcg = dmg b = bcg1 mcb = dmb For xp = xc1 To xc2 WritePixelFast xp, yp, (r Shl 16) Or (g Shl 8) Or b, buffer r = r + dfr g = g + dfg b = b + dfb mcr = mcr + dmr If mcr >= d mcr = mcr - d r = r + rs End If mcg = mcg + dmg If mcg >= d mcg = mcg - d g = g + gs End If mcb = mcb + dmb If mcb >= d mcb = mcb - d b = b + bs End If Next End If End If End If End If End If xp1 = xp1 + df1 xp2 = xp2 + df2 rg1 = rg1 + dfrg1 gg1 = gg1 + dfgg1 bg1 = bg1 + dfbg1 rg2 = rg2 + dfrg2 gg2 = gg2 + dfgg2 bg2 = bg2 + dfbg2 mc1 = mc1 + dm1 mc2 = mc2 + dm2 mcrg1 = mcrg1 + dmrg1 mcgg1 = mcgg1 + dmgg1 mcbg1 = mcbg1 + dmbg1 mcrg2 = mcrg2 + dmrg2 mcgg2 = mcgg2 + dmgg2 mcbg2 = mcbg2 + dmbg2 If mc1 >= dy1 mc1 = mc1 - dy1 xp1 = xp1 + xs1 End If If mc2 >= dy2 mc2 = mc2 - dy2 xp2 = xp2 + xs2 End If If mcrg1 >= dy1 mcrg1 = mcrg1 - dy1 rg1 = rg1 + rsg1 End If If mcgg1 >= dy1 mcgg1 = mcgg1 - dy1 gg1 = gg1 + gsg1 End If If mcbg1 >= dy1 mcbg1 = mcbg1 - dy1 bg1 = bg1 + bsg1 End If If mcrg2 >= dy2 mcrg2 = mcrg2 - dy2 rg2 = rg2 + rsg2 End If If mcgg2 >= dy2 mcgg2 = mcgg2 - dy2 gg2 = gg2 + gsg2 End If If mcbg2 >= dy2 mcbg2 = mcbg2 - dy2 bg2 = bg2 + bsg2 End If Next End If End Function[/code:1:f5e6cd2e05][/b] |
von ??? |
Respekt ;-) |
von ??? |
Schön! Sehr weiche Übergänge! |