L'angolo di 6502Free Span Buffer [3]
2002-12-28
Indice

Benvenuti!
Chi sono
Demo
Documenti
Quelli piccoli
Problemi
Scacchi
Immagini
Musica
Il mio blog
Scrivimi

English version 


Aggiornamento della struttura

Il cuore dell'algoritmo e' la routine che, assegnato un segmento da disegnare, ne disegna le sole parti visibili e al contempo aggiorna la lista di span disponibili. Per vederne il funzionamento consideriamo di voler disegnare il segmento (xa,xb) e guardiamo quali casi si possono presentare per una free span (x0,x1):

Tipi di interazione fra span
In questa figura sono raccolti tutti i possibili tipi di interazione fra un segmento da disegnare (xa,xb) e una span disponibile (x0,x1).

  
Caso 1: x1 <= xa
In questo caso possiamo semplicemente ignorare la span disponibile e passare a considerare la prossima span della scanline.
  
Caso 2: x0<xa; xa<x1<=xb
In questo caso l'area da disegnare e' (xa,x1) e la span deve essere modificata ponendo xa come limite superiore.
  
Caso 3: x0<xa; x1>xb
Questo e' il caso peggiore e richiede il disegno del segmento completo (xa,xb), la modifica del limite superiore della span a xa e la creazione di una nuova span (xb,x1). Una volta effettuate queste operazioni e' pero' possibile considerare conclusa l'elaborazione per questa scanline.
  
Caso 4: x0>=xa; x1<=xb
In questo caso il segmento da disegnare e' (x0,x1) e la span puo' essere rimossa dalla lista di questa scanline. L'elaborazione deve pero' continuare per eventuali altre span presenti.
  
Caso 5: xa<x0<xb; x1>xb
In questo caso il segmento da disegnare e' (x0,xb) e il limite inferiore della span deve essere modificato in xb. Fatto questo l'elaborazione della scanline e' completata.
  
Caso 6: x0>=xb
Questo caso non richiede nessuna elaborazione e indica che non e' necessario proseguire l'analisi di altre span di questa scanline.

La funzione seguente effettua il disegno di un segmento e l'aggiornamento della lista di span della scanline. Si tratta della traduzione in linguaggio C della casistica elencata precedentemente.


void DrawSegment(int y,int xa,int xb)
{
  Span *old,*current,*n;
  for (old=NULL,current=FirstSpan[y];
       current!=NULL;
       old=current,current=current->next)
  {
    if (current->x1<=xa) // Caso 1
      continue;
    
    if (current->x0<xa)
    {
      if (current->x1<=xb) // Caso 2
      {
        DrawPart(y,xa,current->x1);
        current->x1=xa;
      }
      else // Caso 3
      {
        DrawPart(y,xa,xb);
        n=NewSpan();
        n->next=current->next;
        current->next=n;
        n->x1=current->x1;
        current->x1=xa; n->x0=xb;
        return;
      }
    }
    else
    {
      if (current->x0>=xb) // Caso 6
        return;
      
      if (current->x1<=xb) // Caso 4
      {
        DrawPart(y,current->x0,current->x1);
        n=current->next; FreeSpan(current);
        if (old) old->next=n;
            else FirstSpan[y]=n;
        current=n;
        if (current==NULL) return;
      }
      else // Caso 5
      {
        DrawPart(y,current->x0,xb);
        current->x0=xb;
      }
    }
  }
}