Zeichenfunktionen - Gouraud Shading für Polygone

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DivineDominion

Betreff: Zeichenfunktionen - Gouraud Shading für Polygone

BeitragFr, Feb 25, 2005 14:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Habe versucht Gouraudshading einzubauen - geht auch. Der Weg dahin fing aber mit Grundlagen an, die ich hier mal Stück für Stück hinstellen will.

Als erstes das eigentliche Programm von wo aus ich dann alles getestet habe:

Code: [AUSKLAPPEN]

Strict
Framework brl.basic
Import brl.glmax2d
Import brl.pixmap

Graphics 640, 480, 0

'Pixel werden in Pixmap gesetzt - malen ist dann leider lahm...
Global hBack:TPixmap = CreatePixmap( 640, 480, PF_RGBA8888 )

Global hBArr:Byte Ptr[640, 480]

For Local x:Int = 0 Until hBack.width
   
   For Local y:Int = 0 Until hBack.height
      
      hBArr[ x, y ] = PixmapPixelPtr( hBack, x, y )
      
   Next
   
Next

'###################
'Hier kommen Anweisungen hin zum malen später


While Not KeyHit( KEY_ESCAPE )
   
   Cls
   
   DrawPixmap hBack, 0, 0
   
   Flip
   
   FlushMem
   
Wend



Als erstes - und als Basis für alles andere später - werden Pixel gebraucht. Habe eine Funktion zum malen von außerhalb, die aber erst später eingefügt. Daher ist bei manchen Funktionen wohl einiges an unnötigem Speicherverbrauch zu verzeichnen, wenn ich extra einen Punkt erstelle für den Parameter.

Code: [AUSKLAPPEN]

Type TPoint

   Field x:Int, y:Int, z:Int 'Z war für später wichtig
   Field r:Byte, g:Byte, b:Byte

   'Einen Punkt kopieren
   Function clone:TPoint( p:TPoint )
      
      Local temp:TPoint = New TPoint
      
      temp.x = p.x
      temp.y = p.y
      
      temp.r = p.r
      temp.g = p.g
      temp.b = p.b
      
      Return temp
            
   EndFunction
   
   Function create:TPoint( x:Int, y:Int )
      
      Local temp:TPoint = New TPoint
      
      temp.x = x
      temp.y = y
      
      Return temp
      
   EndFunction
   
   Method color( r:Byte, g:Byte, b:Byte )
      
      Self.r = r
      Self.g = g
      Self.b = b
      
   EndMethod
   
   Method set(  )
      
      drawPixel( Self.x, Self.y, Self.r, Self.g, Self.b, 255 )
      Rem
      hBArr[ Self.x, Self.y ][0] = Self.r
      hBArr[ Self.x, Self.y ][1] = Self.g
      hBArr[ Self.x, Self.y ][2] = Self.b
      hBArr[ Self.x, Self.y ][3] = 255
      EndRem
   EndMethod
   
EndType

'Pixel in Buffer setzen (später erst dazugekommen)
Function drawPixel( x:Int, y:Int, r:Byte, g:Byte, b:Byte, a:Byte )
   
   hBArr[ x, y ][0] = r
   hBArr[ x, y ][1] = g
   hBArr[ x, y ][2] = b
   hBArr[ x, y ][3] = a
   
EndFunction

'Grundlegende Funktionen:
'Set/Unset ebdeutet immer weiß oder schwarz, waren die ersten Versuche
'für spätere Funktionen

Function getPointFromPixel:TPoint( x:Int, y:Int )
   
   Local temp:TPoint = TPoint.create( x, y )
   
   Local r:Byte, b:Byte, g:Byte
   r = hBArr[ x, y ][0]
   g = hBArr[ x, y ][1]
   b = hBArr[ x, y ][2]
   
   temp.color( r, g, b )
   
   Return temp
   
EndFunction

Function set_pixel( p:TPoint )
   
   p.color( 255, 255, 255 )
   p.set
   
EndFunction

Function del_pixel( p:TPoint )
   
   p.color( 0, 0, 0 )
   p.set
   
EndFunction

Function isPixelSet( x:Int, y:Int )
   
   If hBArr[x, y][0] = 255 And hBArr[x, y][1] = 255 And hBArr[x, y][2] = 255 Then Return True
   
EndFunction



'Linie "plotten", mit Abständen
Function plot_line( p:TPoint, q:TPoint )
   
   Rem
      Funktionsgleichung:
         y = m * x + b
   EndRem
   
   Local m:Double, b:Double
   
   'Punkt kopieren
   p = TPoint.clone( p )
   
   m = Double( q.y - p.y ) / Double( q.x - p.x )
   b = Double( p.y * q.x - q.y * p.x ) / Double( q.x - p.x )   
   
   While p.x <= q.x
      
      p.y = Int( m * p.x + b + 0.5 )
      
      set_pixel p
      
      p.x :+ 1
      
   Wend
      
   p = Null
   
EndFunction

Function bresenham_line( p:TPoint, q:TPoint )
   
   'Punkt kopieren
   p = TPoint.clone( p )
   
   'Abstand
   Local DiffX:Int, DiffY:Int
   
   DiffX = q.x - p.x
   DiffY = q.y - p.y
   
   '"Richtung" oder sowas
   Local inc_x:Int, inc_y:Int
   
   If DiffX > 0 Then inc_x = 1 Else inc_x = -1
   If DiffY > 0 Then inc_y = 1 Else inc_y = -1
   
   
   Local error:Int, delta:Int, schwelle:Int
   
   If Abs( DiffY ) < Abs( DiffX )
      
      error = -Abs( DiffX )
      delta = 2 * Abs( DiffY )
      schwelle = 2 * error
      
      While p.x <> q.x
         
         set_pixel p
         
         p.x :+ inc_x
         
         error :+ delta
         
         If error > 0
         
            p.y :+ inc_y
            error :+ schwelle
            
         EndIf
         
      Wend
   
   Else
      
      error = -Abs( DiffY )
      delta = 2 * Abs( DiffX )
      schwelle = 2 * error
      
      While p.y <> q.y
         
         set_pixel p
         
         p.y :+ inc_y
         
         error :+ delta
         
         If error > 0
            
            p.x :+ inc_x
            error :+ schwelle
            
         EndIf
         
      Wend
   EndIf
   
   set_pixel q
   
EndFunction

'Linie interpolieren, also Farbverlauf erstellen
Function bresenham_line_interpolated( p:TPoint, q:TPoint )
   
   'Punkt kopieren
   p = TPoint.clone( p )
   
   'Abstand
   Local DiffX:Int, DiffY:Int, Diff:Int
   
   DiffX = q.x - p.x
   DiffY = q.y - p.y
   
   Diff = Sqr( DiffX * DiffX + DiffY * DiffY )
   
   
   'Farbdifferenz
   Local dr:Int = q.r - p.r
   Local dg:Int = q.g - p.g
   Local db:Int = q.b - p.b
   Local dx:Int, dy:Int, d:Int
   Local r:Int, g:Int, b:Int
   
   'Farbe pro pixel
   Local r_pp:Int = dr / Diff
   Local g_pp:Int = dg / Diff
   Local b_pp:Int = db / Diff
      
   '????????
   Local inc_x:Int, inc_y:Int
   
   If DiffX > 0 Then inc_x = 1 Else inc_x = -1
   If DiffY > 0 Then inc_y = 1 Else inc_y = -1
   
   
   Local error:Int, delta:Int, schwelle:Int
   
   If Abs( DiffY ) < Abs( DiffX )
      '0 - 45° (spitz)
      
      error = -Abs( DiffX )
      delta = 2 * Abs( DiffY )
      schwelle = 2 * error
      
      While p.x <> q.x
                  
         dx = - Abs( q.x - p.x )
         dy = - Abs( q.y - p.y )
         d = - Sqr( dx * dx + dy * dy )
         
         r = r_pp * d
         g = g_pp * d
         b = b_pp * d
                        
         p.color( r, g, b )
         p.set(  )
         
         p.x :+ inc_x
         
         error :+ delta
         
         If error > 0
         
            p.y :+ inc_y
            error :+ schwelle
            
         EndIf
         
      Wend
   
   Else
      
      error = -Abs( DiffY )
      delta = 2 * Abs( DiffX )
      schwelle = 2 * error
      
      While p.y <> q.y
         
         dx = - Abs( q.x - p.x )
         dy = - Abs( q.y - p.y )
         d = - Sqr( dx * dx + dy * dy )
         
         r = r_pp * d
         g = g_pp * d
         b = b_pp * d
                  
         
         p.color( r, g, b )
         p.set(  )
                  
         p.y :+ inc_y
         
         error :+ delta
         
         If error > 0
            
            p.x :+ inc_x
            error :+ schwelle
            
         EndIf
         
      Wend
   EndIf

    q.set         
   
EndFunction

Function bresenham_circle( p:TPoint, r:Int )
   
   Local x:Int, y:Int
   
   x = 0
   y = r
   
   Local d:Int, dx:Int, dxy:Int
   
   d = 1 - r
   dx = 3
   dxy = -2 * r + 5
   
   While y >= x

      'Das hier kann man mittlerweile umschreiben
      set_pixel( TPoint.create( p.x + x, p.y + y ) )
      set_pixel( TPoint.create( p.x + y, p.y + x ) )
      set_pixel( TPoint.create( p.x + y, p.y - x ) )
      set_pixel( TPoint.create( p.x + x, p.y - y ) )
      set_pixel( TPoint.create( p.x - x, p.y - y ) )
      set_pixel( TPoint.create( p.x - y, p.y - x ) )
      set_pixel( TPoint.create( p.x - y, p.y + x ) )
      set_pixel( TPoint.create( p.x - x, p.y + y ) )
      
      If d < 0
         
         d :+ dx
         dx :+ 2
         dxy :+ 2
         x :+ 1
      
      Else
         
         d :+ dxy
         dx :+ 2
         dxy :+ 4
         x :+ 1
         y:- 1
         
      EndIf
      
   Wend
EndFunction

'Füllroutine
Function fillRowByRow( x:Int, y:Int )
   
   Local lg:Int, rg:Int
   
   Local hilf:TPoint
   
   Local px = x
   
   While Not isPixelSet( x, y )
      
      hilf = TPoint.create( x, y )
      set_pixel( hilf )
      x :- 1
      
   Wend
   
   lg = x + 1
   
   x = px + 1
   
   While Not isPixelSet( x, y )
      
      hilf = TPoint.create( x, y )
      set_pixel( hilf )
      x :+ 1
      
   Wend
   
   rg = x - 1
   
   For Local pos:Int = rg To lg Step -1
      
      If Not isPixelSet( pos, y - 1 ) Then fillRowByRow( pos, y - 1 )
      
      If Not isPixelSet( pos, y + 1 ) Then fillRowByRow( pos, y + 1 )
            
   Next
   
EndFunction

'"Normale" lineare Interpolation mit Farbe
Function line_interpolated( p:TPoint, q:TPoint )
   
   'Positionsdifferenz
   Local diffX:Int = q.x - p.x
   Local diffY:Int = q.y - p.y
   
   Local arr:TPoint[Abs(diffY)]
   
   'Gesamte Differenz und Erhöhung für Mu
   Local diff:Int = Sqr( diffX * diffX + diffY * diffY )
   Local fac:Float = 1.0 / diff
   
   'Farbdifferenz
   Local dr:Int, dg:Int, db:Int
   dr = q.r - p.r
   dg = q.g - p.g
   db = q.b - p.b
   

   
   'Farben und Koordinaten der Punkte
   Local r:Byte, g:Byte, b:Byte
   Local x:Int, y:Int
       
   Local mu:Float = 0.0
   While mu <= 1.0
   
      x = diffX * mu + p.x
         y = p.y + diffY * mu
       
      'Farbdifferenz * Schritt
      r = p.r + dr * mu
      g = p.g + dg * mu
      b = p.b + db * mu
      r = 255
             
      'Pixel malen
      drawPixel( x, y, r, g, b, 255 )
       
         'Pixelabstand
         mu :+ fac
         
   Wend
   
EndFunction

'Linie für Testzwecke zeichnen
Function ll( p:TPoint, q:TPoint )
   
   Local diffX:Int = q.x - p.x
   Local diffY:Int = q.y - p.y
   
   Local x:Int, y:Float = p.y
   Local delta:Float = 1.0 * diffY / diffX
   
   For x = p.x To q.x
      
      drawPixel( x, y, 255, 255, 0, 255 )
      y :+ delta
      
   Next

EndFunction


Ja, und dann noch fein was zum anschauen (muss an die markeirte Stelle)

Code: [AUSKLAPPEN]

Local p:TPoint = TPoint.create( 10, 10 )
p.color( 255, 128, 0 )
local q:TPoint = TPoint.create( 190, 239 )
q.color( 30, 130, 180 )

line_interpolated( p, q )

local m:TPoint = TPoint.create( 400, 200 )
bresenham_circle( m, 20 )
fillRowByRow( m.x, m.y )
christian.tietze@gmail.com - https://christiantietze.de
macOS
  • Zuletzt bearbeitet von DivineDominion am So, Mai 15, 2005 20:02, insgesamt einmal bearbeitet
 

Dreamora

BeitragFr, Feb 25, 2005 14:53
Antworten mit Zitat
Benutzer-Profile anzeigen
*nicht versteht, was das mit Gouraud Shading zu tun hat*
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.

DivineDominion

BeitragFr, Feb 25, 2005 18:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Nicht so schnell, war beim Schulsport Smile

Also, weiter gehts.

Jetzt kommen Kanten, die ich bei einem Polygon später für eine Edgelist brauche.
Die Koordinaten der einzelnen Punkte werden in einem Array (_raster) gespeichert.
Das ist dann wie bei plot_line, wo für jede X-Koordinate immer nur eine Y-Koordinate existierte, nur eben nun andersrum: Jede Zeile (Y) bekommt ein X zugeordnet. Nicht ganz der mathematische Fubnktionsbegriff aber dafür füllen wir die Abstände von links nach rechts, nicht oben nach unten. Ginge aber wohl auch.

Also das hier irgendwie in eine include-Datei auslagern oder unten an den Code dranhängen.
Code: [AUSKLAPPEN]
   
Type TEdge
   
   Field hStart:TPoint, hEnd:TPoint
   
   Field _height:Int
   Field _xmin:Int, _xmax:Int
   Field _ymin:Int, _ymax:Int

   'Bedeutung der Dimensionen:
   '[0, 2] : [y, x(0) & rgb(1)]
   Field _raster:Int[0,2]
   
   Function create:TEdge( p:TPoint, q:TPoint )
      
      Local temp:TEdge = New TEdge
      
      'Startpunkt soll der Obere sein   
      If q.y < p.y
         
         temp.hStart = q
         temp.hEnd = p
      
      Else
         
         temp.hStart = p
         temp.hEnd = q
         
      EndIf
      
      temp._ymin = temp.hStart.y
      temp._ymax = temp.hEnd.y
      
      Rem
         Breite NICHT +1. damit der unterste Pixel
         ignoriert wird. Dieser untere Punkt wird von
         angrenzenden Polygonen verwendet (für nix anderes
         ist diese Variable sonst zu gebrauchen) und
         so ersetzt.
      EndRem
      
      temp._height = temp._ymax - temp._ymin
      
      
      If p.x < q.x
         
         temp._xmin = p.x
         temp._xmax = q.x
      
      Else
      
         temp._xmin = q.x
         temp._xmax = p.x
         
      EndIf
      
         
      'y -> x, rgb - Liste erstellen
      temp.interpolate(  )
      
      Return temp
      
   EndFunction
         
   Method draw(  )
      
      For Local i:Int = 0 Until Self._height
         
         'Farbe am Punkt der Zeile
         Local rgb:Int = Self._raster[i, 1]
         
         'Farbanteile
         Local r:Int, g:Int, b:Int
         hex_rgb( rgb, r, g, b )
         
         'Position des Punktes der Zeile
         Local x:Int = Self._raster[i, 0]
         Local y:Int = Self.hStart.y + i
         
         'Malen
         drawpixel( Self._xmin + x, y, r, g, b, 255 )
         
      Next      
      
   EndMethod
   
   Method interpolate(  )
      
      'Kürzere Namen
      Local p:TPoint = Self.hStart
      Local q:TPoint = Self.hEnd
      
      'Vertikale Differenz
      Local diffY:Int = q.y - p.y
            
      'Raster entsprechend vergrößern
      Self._raster = New Int[diffY+1, 2]
      
      'Attribute der Geradengleichung
      'Steigung
      Local m:Float = Float( q.y - p.y ) / Float( q.x - p.x )
      
      'Achsenabschnitt
      Local y0:Float = Float( p.y * q.x - q.y * p.x ) / Float( q.x - p.x )   
   
      'Steigung = 0 -> Horizontale
      If m = 0
         
         'Buffer-Punkt
         Local arr_p:TPoint
         
         'Je nachdem, welcher Punkt der Linke ist...
         If p.x < q.x
            
            arr_p = p
         
         Else
            
            arr_p = q
         
         EndIf
         
         '... wird die Koordinate genommen um einen Wert zu speichern
         Self._raster[0, 0] = arr_p.x - Self._xmin
         Self._raster[0, 1] = rgb_hex( arr_p.r, arr_p.g, arr_p.b )
         
         'Funktion verlassen
         Return
                  
      EndIf
      
      
      'Prozentualer Anteil eines Pixels gemessen an der Höhe
      Local verhaeltnis:Float = 1.0 / diffY
      
      'Farbdifferenz vom Start- zum Ednpunkt
      Local dr:Int, dg:Int, db:Int
       dr = q.r - p.r
       dg = q.g - p.g
       db = q.b - p.b
      
      'Die Höhe entlang iterieren
      For Local i:Int = 0 To diffY
         
         'Umformen der Gleichung:
         '    y = mx + y0
         '<=> x = ( y - y0 ) / m
         
         'x-Position an y
         Self._raster[i, 0] = Int( ( ( p.y + i ) - y0 ) / m ) - Self._xmin
         
         
         'Fortschritt "in %", relativ zur Höhe
         Local schritt:Float = i * verhaeltnis
         
         'Farbanteile
         Local r:Int = 0, g:Int = 0, b:Int = 0
         
         'Grundfarbe + ( Differenz * Fortschritt )
         r = p.r + dr * schritt
          g = p.g + dg * schritt
          b = p.b + db * schritt
         
         'Farbwert in Hex
         Local rgb:Int = rgb_hex( r, g, b )
         
         'Farbe speichern
         Self._raster[i, 1] = rgb
         
      Next
      
   EndMethod
         
EndType

'Farbumwandlung (Hex wird im Array gespeichert, da nur eine einzige Zahl)
Function rgb_hex( r:Byte, g:Byte, b:Byte )
   
   Return ( r Shl 16 ) | ( g Shl 8 ) | b
   
EndFunction

Function hex_rgb( rgb:Int, r:Int Var, g:Int Var, b:Int Var )
   
   r = (rgb Shr 16) & $ff
   g = (rgb Shr 8) & $ff
   b = rgb & $ff
   
EndFunction




Neues Beispiel für besagte Stelle im Hauptcode:
Code: [AUSKLAPPEN]

local p:TPoint = TPoint.create( 10, 10 )
p.color( 255, 255, 0 )
local q:TPoint = TPoint.create( 213, 423 )
q.color( 0, 0, 255 )

local e:TEdge = TEdge.create( p, q )
e.interpolate '_raster erstellen
e.draw
christian.tietze@gmail.com - https://christiantietze.de
macOS

DivineDominion

BeitragFr, Feb 25, 2005 18:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Und dann kommen eben die Polygone. Habe ehrlichgesagt nur konvexe Polygone getestet, und zwar Dreiecke Wink

Das Raster sit nun zweidimensional.
soll heißen, dass wir nicht nur für jede Zeile (Y) ein X speichern. Diesmal haben wir nämlich xStart und xEnd für jede Zeile, zwischen denen ausgefüllt wird.
Die erste Dimension ist, wie im Code gleich kurz angedeutet, die Zeile (0 bis höhe - 1). Die zweite steht entweder xStart (links, 0) oder xEnd (rechts, 1). Wir interpoleiren horizontal von links nach rechts, deswegen.
Die dritte Dimension hat dann für den jeweiligen X-Punkt die Koordinate (0) als auch die Farbe für den Punkt (1).

Hmm, ja, anhängen und Beispiel unten testen.

Code: [AUSKLAPPEN]
   
Type TPoly
   
   Field _xmin:Int, _xmax:Int
   Field _ymin:Int, _ymax:Int
   Field _height:Int
   
   '[0, 2, 2] : [y, links (0) | rechts (1), x (0) | rgb (1)]
   Field _raster:Int[0,2,2]
   
   Field hEdgeList:TList
   
   Method New(  )
      
      Self.hEdgeList = CreateList(  )
      
   EndMethod
      
   Method draw(  )
      
      Local h:Int = Self._ymax - Self._ymin
      
      For Local i:Int = 0 To h - 1
         
         'Relativer y-Wert + absolute Position
         Local y:Int = i + Self._ymin
         
         'Linker Punkt
         
         Local x1:Int = Self._raster[i, 0, 0] + Self._xmin
         
         Local rgb1:Int = Self._raster[i, 0, 1]
         Local r1:Int, g1:Int, b1:Int
         hex_rgb( rgb1, r1, g1, b1 )
         
         Local x2:Int = Self._raster[i, 1, 0] + Self._xmin
         Local rgb2:Int = Self._raster[i, 1, 1]
         Local r2:Int, g2:Int, b2:Int
         hex_rgb( rgb2, r2, g2, b2 )
         
         
         'Abstand zwischen Punkten   
         Local dx:Int = x2 - x1
         
         'Farbdifferenz
         Local dr:Int, dg:Int, db:Int
         dr = r2 - r1
         dg = g2 - g1
         db = b2 - b1
         
         'Abstand "in %"
         Local verhaeltnis:Float = 1.0 / dx
         
         For Local j:Int = 0 To dx
            
            'Relative Distanzüberbrückung + Startposition
            Local x:Int = j + x1
            
            'Fortschritt "in %" = Distanzüberbrückung * %
            Local schritt:Float = j * verhaeltnis
            
            'Farbe = Farbbasis + Fortschritt zur Zielfarbe
            Local r:Int = r1 + dr * schritt
            Local g:Int = g1 + dg * schritt
            Local b:Int = b1 + db * schritt
            
            drawPixel( x, y, r, g, b, 255 )
            
         Next
         
         
         drawPixel( x1, y, r1, g1, b1, 255 )
         
         
         ''drawPixel( x2, y, r2, g2, b2, 255 )
         
      Next
      
      
      
   EndMethod
      
   Method addEdge( edge:TEdge )
      
      Self.hEdgeList.addLast( edge )
      
   EndMethod
   
   Method mergeEdges(  )
      
      Self._xmin = GraphicsWidth(  )
      Self._xmax = 0
         
      Self._ymin = GraphicsHeight(  )
      Self._ymax = 0
         
      For Local edge:TEdge = EachIn Self.hEdgeList
                  
         If edge._xmin < Self._xmin Then Self._xmin = edge._xmin
         If edge._xmax > Self._xmax Then Self._xmax = edge._xmax
   
         If edge._ymin < Self._ymin Then Self._ymin = edge._ymin
         If edge._ymax > Self._ymax Then Self._ymax = edge._ymax
         
      Next
      
      Self._height = Self._ymax - Self._ymin + 1
      
      'Jedes Y hat 2 X - links und rechts
      Local arr:Int[Self._height, 2, 2]
      
      
      For Local h:Int = 0 Until Self._height
         
         arr[h, 0, 0] = -1
         arr[h, 1, 0] = -1
         
      Next
      
      For Local edge:TEdge = EachIn Self.hEdgeList
         
         'Local i:Int
         
         'Kante - Start = Relative Anfangsposition
         Local dy:Int = edge._ymin - Self._ymin
         Local dx:Int = edge._xmin - Self._xmin
                  
         For Local i:Int = 0 Until edge._height
            
            'Y = Anfangsposition + Schritt
            Local y:Int = dy + i
            Local x = edge._raster[i, 0] + dx
            Local rgb = edge._raster[i, 1]
            
            If arr[y, 0, 0] > -1
               'Schon gesetzt
                  
               If arr[y, 0, 0] > x
                  'Größer als aktueller Wert
                  
                  'Wert verswhcieben und neuen speichern
                  arr[y, 1, 0] = arr[y, 0, 0] 'x
                  arr[y, 1, 1] = arr[y, 0, 1] 'rgb
                  
                  arr[y, 0, 0] = x
                  arr[y, 0, 1] = rgb
               
               Else
                  'Wert ist größer als gespeicherter
                  
                  arr[y, 1, 0] = x
                  arr[y, 1, 1] = rgb
                  
               EndIf
            
            Else
               'Nicht vorhanden => links (0) speichern
               
               arr[y, 0, 0] = x
               arr[y, 0, 1] = rgb
               
            EndIf
                        
         Next
         
      Next
      
      Self._raster = arr
      
   EndMethod
   
EndType




Hier das Beispiel:
Code: [AUSKLAPPEN]
'Eckpunkte
local p_a:TPoint = TPoint.create( 10, 300 )
p_a.color 255, 0, 0
local p_b:TPoint = TPoint.create( 312, 140 )
p_b.color 0, 255, 0
local p_c:TPoint = Tpoint.create( 200, 10 )
p_c.color 0, 0, 255

'Seitenkanten
local e_a:TEdge = TEdge.create( p_b, p_c )
local e_b:TEdge = TEdge.create( p_a, p_c )
local e_c:TEdge = TEdge.create( p_a, p_b )

'Kanten interpolieren (sonst ist array leer)
e_a.interpolate
e_b.interpolate
e_c.interpolate

'Dreieck
local poly:TPoly = new TPoly
poly.addEdge e_a
poly.addEdge e_b
poly.addEdge e_c
poly.mergeEdges
poly.draw
christian.tietze@gmail.com - https://christiantietze.de
macOS

Vertex

BeitragFr, Feb 25, 2005 19:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Ahh, wunderbar! Hast du schonmal ein paar Speed-Tests gemacht, ob man das event. für Softwarerendering benutzen kann? So 2000 Triangles bei flüssiger FPS Rate wären schon ganz gut.

Gut gefällt mir, das alles aufeinander aufbaut. Kenne noch die anderen Gouraudshading Funktionen hier im Forum, wo man nichtmehr durchgesehen hat.

Benutzt du direkt den Gouraudalgorithmus? Wenn ja, wäre vllt. ganz gut, wenn du ihn nochmal mit eigenen Worten erklährst.

mfg olli
vertex.dreamfall.at | GitHub

DivineDominion

BeitragFr, Feb 25, 2005 20:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Wer Theorie will:
http://www-lehre.informatik.un...0000000000

Habe damit angefangen früher mal, und diesmal hab ich auch versucht es zu verstehen Wink
Rastern von Dreiecken sit eben das man von oben nach unten (Scanline) die Start- und Endpunkte (xMin und xMax bzw. xStart und xEnd) speichert und dann dazwischen ansich bloß interpoliert. Naja zumindest wird oft das Wort "interpolieren" erwähnt etc und die Formel konnte ich auch entsprechend "umdingsen" Smile

user posted image

Das mache ich im Prinzip beim Rastern der Kanten (Tedge.interpolate) und das Füllen dann auch anders:
user posted image

Ich weiß nicht ob es so anders aussehen würde, aber ich kann Farben schlecht addieren und dachte mir, dass es so schneller wäre als für jeden Pixel x2-xi zu rechnen etc...


Naja das Zeug ist saulahm, übrigens Smile
christian.tietze@gmail.com - https://christiantietze.de
macOS

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group