Post on 08-Aug-2019
WiederholungWiederholung
Letzte Woche1001 10101000
AB
Letzte WocheLinien zeichnenLinien Clipping 00000001 0010
A
EH
pp g• Cohen-Sutherland:
Rechteckiges Clip-Polygon
C
D
F
G
HeuteLinien Clipping
0100 01100101
0& 21 ≠ccLinien Clipping
• Beliebiges, konvexes Clip-Polygon
0| 21 ==ccLinie vollständig außerhalb, fertig.
Linie vollständig innerhalbPolygon an Polygon clippen
Linie vollständig innerhalb, alles zeichnen.
Sonst: neue Punkte durch Clipping bestimmen und
T. Grosch - 2 -
Clipping bestimmen und wiederholen
Cyrus-Beck (1978)Cyrus-Beck (1978)Clippen von Linien mitClippen von Linien mit beliebigen, konvexen PolygonzügenV d t diVerwendet die Parameterdarstellung der Linien
Clip-Objekt Clip-Objekt
Im Folgenden wird wieder das Rechteck als Beispiel verwendet; der Algorithmusverwendet; der Algorithmus ist aber für beliebige (konvexe) Polygonzüge anwendbaranwendbar.
Clip-Objekt Clip-Objekt
T. Grosch - 3 -
GeradenschnittGeradenschnittDas Clip-Objekt besteht aus
B2P3PDas Clip Objekt besteht aus
einer Reihe von Linien, die der Reihe nach mit der zu zeichnenden Liniezeichnenden Linie geschnitten werden.Mathematisch gesehen sind
P Pdies Geraden Es kann bei einem n-Eck bis zu n Geradenschnittpunkte
0PA 1P
)( ABAXzu n Geradenschnittpunkte geben (Bsp. hier 4-Eck, also auch 4 Schnittpunkte)
)( ABtAX −⋅+=
vtAX v⋅+= vtAX +
ABv −=v
T. Grosch - 4 -
SchnittpunktberechnungSchnittpunktberechnungMan bestimmt jeweils die 2P3PMan bestimmt jeweils die nach außen zeigende Normale auf die Clip-Kante.F tl t tFestlegung: man erwartet, dass der Polygonzug gegen den Uhrzeigersinn definiert
P Pkv
ist.Beispiel:
0P 1P
vnv
0110 PPPPk −==
⎞⎛ k ⎞⎛ k
Beispiel in Werten
⎟⎞
⎜⎛1
⎟⎞
⎜⎛ 0
⎟⎟⎠
⎞⎜⎜⎝
⎛=
y
x
kk
kv
⎟⎠
⎞⎜⎝
⎛−
=x
y
kk
nv ⎟⎠
⎞⎜⎝
⎛=
01
kv
⎟⎠
⎞⎜⎝
⎛−
=1
0nv
T. Grosch - 5 -
SchnittpunktberechnungSchnittpunktberechnungGeradengleichung der zu
B2P3P
2nv
Geradengleichung der zu zeichnenden Linie in Parameterform
tAX v 1nv3nv
Geradengleichung der Clip-Kante in Normalform P P
vtAX v⋅+= 1n3n
0PA 1P0)( =− ii PXn o
v
0nv
Einsetzen liefert:
0)( =−⋅+ ii PvtAn vo
v vnPAnt
i
iiv
ovo
v )( −−=
0)( =⋅+− vntPAn iiiv
ov
ov
i
T. Grosch - 6 -
ProblemProblemWie bestimmt man die Linie 2Wie bestimmt man die „tatsächlichen“ (im Gegensatz zu den virtuellen“) Schnittpunkte ? 1=t
Linie 2
„virtuellen ) Schnittpunkte ?Zuerst sicherstellen, das t ∈[0,1]
2P3P
Idee: Sortieren der t-Werte und die mittleren verwenden.Problem: damit erkennen wir PProblem: damit erkennen wir nicht die Liniensegmente, die außerhalb des Clip-Objekts liegen (Linie 2)
0P1P
0=t
liegen (Linie 2)
T. Grosch - 7 -
Lösung BLösungDer Polygonzug des Clip-
1+iP
1wvDer Polygonzug des ClipObjekts hat eine Normale, die nach außen zeigtFü j d Cli K t k A inv
1w
Für jede Clip-Kante kann man daher einfach bestimmen, ob Start- und
A
0wv
Endpunkt der zu zeichnenden Linie im vorderen/hinteren Halbraum liegen.
iP
0Beispiel:g
Hierzu nimmt man einen Punkt der Clip-Kante (z.B. Pi) und berechnet jeweils das
00 <inw vo
v
weil Winkel > 90°Punkt innerhalbund berechnet jeweils das
Skalarprodukt mit der Normalen.
01 >inw vo
vPunkt innerhalb
Weil Winkel < 90°Punkt außerhalb
T. Grosch - 8 -
Einfacher Test auf VorzeichenEinfacher Test auf Vorzeichen
B00 d vvvv
1+iPB00 10 << ii nwundnw v
ovv
ov
Beide Punkte liegen innerhalb des Clip Objekts in Bezug auf die
nv1wv
00 ≥≥ nwundnw vo
vvo
v
Clip-Objekts in Bezug auf die untersuchte Kante
A in
0wv00 10 ≥≥ ii nwundnw oo
Beide Punkte liegen außerhalb des Clip-Objekts; die Linie muss nicht
iP
0Clip Objekts; die Linie muss nicht gezeichnet werden
sonstEs gibt einen Schnittpunkt; t berechnen.
T. Grosch - 9 -
In/OutIn/Out
0vv B1+iP
0<inv vov
Wir treten an dieser Kante in das Objekt ein (In)
B
nv0>nv vov
Objekt ein (In) outvv
in0>inv oWir verlassen das Objekt an dieser Kante (Out)
A
Kante (Out)
sonst Avvin
iP
Sonderfall, der anderweitig abgefangen wird.
AB
i
T. Grosch - 10 -
B BB2P
B
vOut
0P P P
1nv
In
0 1PA
1PA
0nv
B2nv
B2P3P 3P
3nvOut
OutOut
0P
In
InA A In
Vermutung liegt nahe: größter t_in Wert und kleinster t_out Wert
T. Grosch - 12 -
B B
A
2P
A1nv
0P1P
0nv
B B
1P
2P3P
2nv
3POutIn
Out
A A3nv
0P
Abbruch: wenn t_in größer t_out Wert
T. Grosch - 13 -
Cyrus-BeckCyrus-Beckvoid clipAndDraw(Vector2D a, Vector2D b){
c0 = dot(w0, n);c1 = dot(w1, n);
Vector2D v,w0,w1,n;float t, tIn, tOut, c0, c1, nenner;int i;
if (c0 > 0 && c1 > 0)return;
if (c0 <= 0 && c1 <= 0)v = b - a;tIn = 0.0;tOut = 1.0;
continue;
nenner = dot(v,n );t = -c0/nenner; Division durch nenner?
for (i=0; i<4; i++){
int iNext = (i+1) % 4;n.setX( clipPoints[iNext].y() -
if (nenner < 0 && t > tIn)tIn = t;
if (nenner > 0 && t < tOut)
Division durch nenner?
clipPoints[i].y() ); n.setY( - (clipPoints[iNext].x() -
clipPoints[i].x()) );
tOut = t;}if (tIn > tOut)
return; In die Schleife ?w0 = a - clipPoints[i];w1 = b - clipPoints[i]; b = a + tOut * v;
a = a + tIn * v;drawLine(a, b);
In die Schleife ?
d a e(a, b);}
T. Grosch - 14 -
Betrachtung des Nenners 1+iPB
Betrachtung des NennersWann kann der Nenner Null A inv
1wvvv
Wann kann der Nenner Null werden?
PAnt ii ov )( −
−= P
A i
0wv
Zu zeichnende Linie parallel zu
vnt
iv
ov=
0=vv0=vni
vo
viP
Start- und Endpunkt der Linie sind identisch (muss vorher abgefangen werden)
peiner Kante des Clip-Objekts.
Keine Division durch Null da
0=v
vorher abgefangen werden)
Passiert, wenn 2 Punkte des
Keine Division durch Null, da dieser Fall vorher abgefangen wird:
• Linie komplett innerhalb/außerhalb
0=inv
Clip-Objekts identisch sind, vorher abfangen.
pif (c0 > 0 && c1 > 0)
return;if (c0 <= 0 && c1 <= 0)
continue;continue;
T. Grosch - 15 -
Zusammenfassung: Cyrus-BeckZusammenfassung: Cyrus-BeckClipping von Linien an Start- und Endpunkt der zuClipping von Linien, an beliebigen, konvexen PolygonzügenE k kt d Cli Obj kt
Start und Endpunkt der zu zeichnenden Linie werden für jede Kante mit Hilfe eines In/Out Tests klassifiziertEckpunkte des Clip-Objekts
müssen gegen den Uhrzeigersinn definiert werden
In/Out-Tests klassifiziertSkalarprodukt zwischen Normale und Verbindung Kante Linienpunkt(„counterclockwise“)
Degenerierte Kanten (identische Eckpunkte) müssen vorher
Kante-LinienpunktBeiden innen: weitermachen ohne SP BerechnungEckpunkte) müssen vorher
abgefangen werdenBerechnung der Normalen auf die Kanten des Clip Objekts
Beide außen: aufhören.Falls SP berechnet wird, wird dieser ebenfalls als In/Out-die Kanten des Clip-Objekts,
wobei Normalen nach außen zeigen
Punkt klassifiziert.
T. Grosch - 17 -
AusgangspunktAusgangspunkt
Wir haben gesagt dass die Applikation“ sicherstellenWir haben gesagt, dass die „Applikation sicherstellen muss, dass put_pixel(x,y) nur für gültige Pixel aufgerufen wird.gBisher Clipping von Linien:
Cohen-Sutherland: Clippen von Linien an rechteckigen Objekten mit Hilfe von Bereichscodes.Cyrus-Beck: Clippen von Linien an beliebigen, konvexen PolygonzügenPolygonzügen
Clipping von Polygon gegen Polygon:Sutherland-Hodgmang
T. Grosch - 19 -
Sutherland-HodgmanSutherland-Hodgman
Clipping eines Polygonzugs gegen ein konvexes Clip-Clipping eines Polygonzugs gegen ein konvexes Clip-Polygon (z.B. Bildschirm); der Polygonzug darf konkav sein.
Polygonzug (4 Punkte)
Ergebnis (9 Punkte)
Bildschirm
T. Grosch - 20 -
VorgehenVorgehen
Der Polygonzug wird der Reihe nach an den Clip-Kanten geschnitten.
T. Grosch - 21 -
VorgehenVorgehen
Das Ergebnis muss wieder ein geschlossenerDas Ergebnis muss wieder ein geschlossener Polygonzug sein.Als Eingabe dient die Liste der Eckpunkte in derAls Eingabe dient die Liste der Eckpunkte in der richtigen Reihenfolge (gegen den Uhrzeigersinn).Die Routine gibt – nach dem Schnitt mit der jeweiligen g j gClip-Kante - eine neue Liste von Eckpunkten zurück.Wichtig: die Reihenfolge muss stimmen.
T. Grosch - 22 -
4 Fälle4 FälleB
Annahme: der Startpunkt A wurde bereits behandelt
S
AB Beide Punkte Linie „zeigt“ nach
S
ABeide Punkte drinnen:Output B
Linie „zeigt nach außen:Output S
AB
AS A
B Linie „zeigt“ nach Beide Punkte
S
„ ginnen:Output S, B
draußen:Output (nichts)
T. Grosch - 23 -
Beispiel 1D
Beispiel 11S
2S
A C
BInput: A B C D
BOutput: A B C 2S1S
Man beginnt mit der Kante letzter Punkt (D) – erster Punkt (A)g ( ) ( )
T. Grosch - 24 -
Beispiel 2 S SBeispiel 22S
1S 3S
A C6S
A C
5S
SInput:
B4S
A B C 2S1S
Output: A C1S 4S 5S 6S3S
T. Grosch - 25 -
PseudoCodePseudoCodeDiese Routine wird der Reihe nach für jede Clip Kante
Polygon SutherlandHodgman(Polygon poly, Edge clipedge)
{A ist letzter Punkt des Polygons;nach für jede Clip-Kante
aufgerufen. „Innerhalb/Außerhalb“: hier wird
yg ;Schleife über alle Ecken B des Polygons {Wenn B innerhalb von clipedge
wieder die Normale auf die Kante berechnet und mit Hilfe des Vorzeichens des
p gWenn A innerhalb von clipedge
Output (B);else
{
Skalarproduktes entschieden.„Output“: stellt ein neues Polygon zusammen das am
{S = Schnittpunkt (A,B,edge);Output(S), Output(B);}
elsePolygon zusammen, das am Ende zurückgegeben wird.„Schnittpunkt“ berechnet den
elseWenn A innerhalb von clipedge
{S = Schnittpunkt (A,B,edge);Output(S);Schnittpunkt mit der Clipkante,
wobei nur Punkte zw. A und B berechnet werden dürfen.
Output(S);}
A = B;}
Ergebnis von Output zurückgebenErgebnis von Output zurückgeben.
}
T. Grosch - 26 -
Sutherland-HodgmanSutherland-Hodgman
Clipping eines Polygonzugs gegen ein konvexes Clip-Clipping eines Polygonzugs gegen ein konvexes Clip-Polygon (z.B. Bildschirm); der Polygonzug darf konkav sein.Problem: unnötige Kanten können am Rand entstehen, was nicht unbedingt zu Fehlern führt; aus Effizienzgründen können diese nachträglich gelöscht werden.Lä t i h h t l Pi li i H dLässt sich sehr gut als Pipeline in Hardware umsetzen.Erweiterung für konkave Clip Polygone:Erweiterung für konkave Clip-Polygone:
Weiler-Atherton
T. Grosch - 28 -
Füllen von PolygonenFüllen von Polygonen
Eine Anwendung für ein geclipptes Polygon besteht imEine Anwendung für ein geclipptes Polygon besteht im ausgefüllten Zeichnen des Polygons
Bei einfachem Clipping „Linie-für-Linie“ würde kein pp ggeschlossener Polygonzug entstehen kein „Innen“ definiert
Wie füllt man Polygone ?Berechne umgebendes Rechteck des Polygons und teste für jedes Pixel, ob es innerhalb liegt (siehe Shirley: Fundamentals of Computer Graphics)p p )Der Test „Punkt-innerhalb-Polygon“ lässt sich implementieren, indem für jede Kante gestetet wird, ob der Punkt in der negativen Halbebene liegtnegativen Halbebene liegt
T. Grosch - 29 -
Füllen von PolygonenFüllen von Polygonen
Berechnung Bounding BoxPunkt innerhalb Dreieck:
Punkt liegt in der negativen Halbebene aller KantenBerechnung Bounding Boxx_min = x_max = x_1;y_min = y_max = y_1;Fü ll E k kt i 2 N
2PmaxyFür alle Eckpunkte i = 2..N
x_min = min(x_i, x_min)x_max = max(x_i, x_max)
i i ( i i )
maxy
y_min = min(y_i, y_min)y_max = max(y_i, y_max)
C
minyD i k füll
0P1P
minx maxx
Dreieck ausfüllenFor y = y_min…y_max
For x = x min x maxFor x = x_min..x_maxFalls (x,y) innerhalb Dreieck
Pixel setzen
T. Grosch - 30 -
Füllen von PolygonenFüllen von Polygonen
Möglicherweise viele leere Pixel daher gibt es einMöglicherweise viele leere Pixel, daher gibt es ein effizienteres Verfahren:
Kantenlisten• Bestimme y_min, y_max• Durchlaufe alle Zeilen von y_min..y_max
• Verwende Liste „aktiver“ Kanten (schneiden aktuelle Zeile)• Bestimme Schnittpunkte der Kanten mit der Zeile• Verbinde Schnittpunkte mit waagerechter Line (span)p g ( p )
Jede Kante speichert• Inverse Steigung (1/m): Korrekturwert in x-Richtung
d W t d b E d kt d K t K t• y_end : y-Wert des oberen Endpunkts der Kante Kante aus Liste entfernen, evtl. neue Kante einfügen
Siehe: Foley, van Dam: Computer Graphics, Principles and Practice
T. Grosch - 31 -
Füllen von PolygonenFüllen von Polygonen
BeispielBeispiel
maxy
spanminx maxxListe „aktiver“ Kanten
Pro aktiver Kante:x 1/m y end
miny
x, 1/m, y_end
x
T. Grosch - 32 -
Bilineare InterpolationBilineare InterpolationBeim Füllen des Polygons könnenBeim Füllen des Polygons können die Eckpunktwerte (z.B. Eckpunktfarben) interpoliert werden c ′′′
Interpoliert wird zunächst über die Kanten c´,c´´ c′ c ′′
Danach wird zwischen diesen W t i it M l ( tl dWerten ein zweites Mal (entlang der Zeile) interpoliert c´´´
T. Grosch - 33 -
Punkte Linien FlächenPunkte, Linien, Flächen
Alle bisher behandelten Algorithmen zumAlle bisher behandelten Algorithmen zumZeichnen von PunktenZeichnen von Linien (mit Clipping und linearer Interpolation ( pp g pvon Eckpunktwerten z.B. Farbe)…
i d i O GL h ffi i t i l ti t d… sind in OpenGL sehr effizient implementiert und auch entsprechend auf die Möglichkeiten der Graphik-Hardware abgebildetHardware abgebildet.OpenGL bietet uns daher eine wichtige Bibliothek zur Erstellung von graphischen Systemen (API:Erstellung von graphischen Systemen (API: application programming interface)
T. Grosch - 35 -
NamenstypisierungNamenstypisierung
Funktionen mit verschiedenen Parametern tragen Typ undFunktionen mit verschiedenen Parametern tragen Typ und Dimension im Namen:
gl<FUNC>{1234}{b,ub,s,us,i,ui,f,d}[v](...)g { }{ , , , , , , , }[ ]( )
1,2,3,4: Dimension der Argumente
b ub s us i ui f d: Typ: GLbyte GLubyte etc Sonderfall:b,ub,s,us,i,ui,f,d: Typ: GLbyte, GLubyte, etc. Sonderfall: GLclampf, GLclampd
optional können Parameter auch als Vektor übergebenoptional können Parameter auch als Vektor übergeben werden, gekennzeichnet durch das abschließende v
T. Grosch - 36 -
NamenstypisierungNamenstypisierung
Beispiel: glColor{34}{b ub s us i ui f d}[v]( )Beispiel: glColor{34}{b,ub,s,us,i,ui,f,d}[v](...)
GLfloat f[3] = { 0 0 0 5 1 0 };GLfloat f[3] = { 0.0, 0.5, 1.0 };GLubyte b[4] = { 0, 128, 255, 255 };glColor3f( 0 0 0 5 1 0 );glColor3f( 0.0, 0.5, 1.0 );glColor3fv( f );glColor4ubv( b );glColor4ubv( b );
T. Grosch - 37 -
OpenGL: PunkteOpenGL: Punkte
OpenGL setzt Primitive aus einzelnen EckpunktenOpenGL setzt Primitive aus einzelnen Eckpunkten zusammenGenereller Ablauf:Genereller Ablauf:glBegin( GL_… );glVertex...(...);...glEnd();
V t il k i i D t t kt ötiVorteil: keine eigenen Datenstrukturen nötig
T. Grosch - 38 -
Beispiel: EckpunkteBeispiel: Eckpunkte
float fpos[3]={ 10 0 0 };float fpos[3]={ 10, 0, 0 };unsigned short sx=10,sy=0,sz=0;glVertex2i( 10 0 );glVertex2i( 10, 0 );glVertex3s( sx, sy, sz );glVertex3fv( fpos);glVertex3fv( fpos);glVertex4d( 10.0, 0.0, 0.0, 1.0 );
bestimmen alle den gleichen Punktbestimmen alle den gleichen PunktHomogene Koordinate wird von der Applikation in der Regel nicht verwendet Wenn sie weggelassen wirdRegel nicht verwendet. Wenn sie weggelassen wird (3D-Vektor) wird sie als 1 angenommen.
T. Grosch - 39 -
Primitivspezifische EinstellungenPrimitivspezifische Einstellungen
Punkte: Größe mittelsPunkte: Größe mittels glPointSize( GLfloat size );
nicht jede Größe unterstützt über glGet() abzufragennicht jede Größe unterstützt, über glGet() abzufragenWenn Antialiasing abgeschaltet ist (default), dann ist der Punkt ein Quadrat von size*size Pixeln. Nicht-Integer Werte
d d twerden gerundet.glDisable(GL_POINT_SMOOTH);
Wenn Antialiasing eingeschaltet ist dann wird ein KreisWenn Antialiasing eingeschaltet ist, dann wird ein Kreis gezeichnet. Nicht-Integer Werte für size werden hier nicht gerundet.
lE bl (GL POINT SMOOTH)glEnable(GL_POINT_SMOOTH);Evtl. zusätzlich angeben:glEnable(GL_BLEND);glBlendFunc(GL SRC ALPHA GL ONE MINUS SRC ALPHA);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glHint(GL_POINT_SMOOTH, GL_NICEST);
T. Grosch - 40 -
Aktivieren / InaktivierenAktivieren / InaktivierenViele Features müssen explizit aktiviert werdenViele Features müssen explizit aktiviert werden
glEnable( GLenum feature );
I kti i di t dzum Inaktivieren dient dann glDisable( GLenum feature );
der Zustand kann abgefragt werden mittelsglIsEnabled( GLenum feature );
die Konstanten können nicht verodert werden
T. Grosch - 41 -
LinienLinien
Linien: Breite mittelsLinien: Breite mittelsglLineWidth( GLfloat width );
ähnlich wie Punkte nicht jede Größe möglichähnlich wie Punkte nicht jede Größe möglichWenn Antialiasing abgeschaltet ist (default), dann ist width die Breite der Linie in Pixeln (also unabhängig von F t öß ) Ni ht I t W t d d tFenstergröße…). Nicht-Integer Werte werden gerundet.
glDisable(GL_LINE_SMOOTH);Wenn Antialiasing eingeschaltet ist dann wird die HelligkeitWenn Antialiasing eingeschaltet ist, dann wird die Helligkeit der Pixel abhängig vom Bedeckungsgrad berechnet. Nicht-Integer Werte werden hier nicht gerundet.
lE bl (GL LINE SMOOTH)glEnable(GL_LINE_SMOOTH);Evtl. zusätzlich angeben:glEnable(GL_BLEND);glBlendFunc(GL SRC ALPHA GL ONE MINUS SRC ALPHA);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glHint(GL_LINE_SMOOTH, GL_NICEST);
T. Grosch - 42 -
StrichelungenStrichelungen
Gestrichelte Linien definierbar: glLineStipple( GLint factor, GLushort pattern );
Muster aus der Binärdarstellung von pattern8 4 2 1 8 4 2 1 8 4 2 1 8 4 2 1
0xaaaa0x1010
factor vervielfacht die einzelnen Bitsfactor vervielfacht die einzelnen Bits0xaaaa 10xaaaa 3
muß mit glEnable( GL_LINE_STIPPLE ); aktiviert werden
T. Grosch - 43 -
void display(void){
int i;
/* 3. Zeile 2 Linien mit untersch. Stripple */glEnable (GL_LINE_STIPPLE);glLineWidth (1.0);
glClear (GL_COLOR_BUFFER_BIT);glColor3f (0.0, 0.0, 0.0);
g ( )
glLineStipple (1, 0x0101); /* dotted */glBegin(GL_LINES);
glVertex3f(-0.75, -0.25, 0);/* 1. Zeile rechteckige Punkte */
for (i = -9; i < 10; i ++){
glPointSize(10+i);
glVertex3f( 0.75, 0.25, 0);glVertex3f( 0, -0.25, 0);
glEnd();glLineStipple (1, 0x00FF); /* dashed */glBegin(GL LINES);glPointSize(10+i);
glBegin(GL_POINTS);glVertex3f(i/10.0, 0.75,0);
glEnd();}
glBegin(GL_LINES);glVertex3f( 0, -0.25, 0);glVertex3f( 0.75, -0.25, 0);
glEnd(); }
/* 2. Zeile Anti-aliased Punkte */glEnable(GL_POINT_SMOOTH);for (i 9 i < 10 i ++)
/* 4. Zeile 2 dicke Lin. m. untersch. Stripple */glLineWidth (5.0);glLineStipple (1, 0x0101); /* dotted */glBegin(GL LINES)for (i = -9; i < 10; i ++)
{glPointSize(10+i);glBegin(GL_POINTS);
lV t 3f(i/10 0 0 25 0)
glBegin(GL_LINES);glVertex3f(-0.75, -0.75, 0);glVertex3f( 0, -0.75, 0);
glEnd();lLi Sti l (1 0 00FF) /* d h d */glVertex3f(i/10.0, 0.25,0);
glEnd();}glDisable(GL_POINT_SMOOTH);
glLineStipple (1, 0x00FF); /* dashed */glBegin(GL_LINES);
glVertex3f( 0, -0.75, 0);glVertex3f( 0.75, -0.75, 0);
glEnd(); glFlush ();
}T. Grosch - 44 -