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!



Suche:
(unterstützt mySQL Wildcards ala %)
Titel:
Text:
Autor: