Zylinder
Inhaltsverzeichnis
Allgemein
Der folgende Code zeichnet einen Zylinder in einem Würfel der Kantenlänge 2. Dadurch lassen sich beim Zeichnen die Positionskoordinaten auch direkt für die Normalen des Zylinders nutzen. Der Körper des Zylinders sowie die Endkappen werden mit der aktuell gebundene Textur gezeichnet. Will man jede der Flächen mit einer anderen Textur versehen, so muss diese zwischen den einzelnen Abschnitten gewechselt werden.
Verwendete Typen
Type
TVector3f = Record
x, y, z : Single;
End;
Parameter
Der einzige Parameter n der Prozedur bestimmt die Anzahl der Unterteilungen des Zylinders. Die Größe des Objektes wird durch ein vorangehendes glScalef festgelegt, welches als Parameter jeweils die Radien des Objektes in den verschiedenen Koordinatenachsen enthält.
Procedure
Procedure DrawCylinder(n : Byte);
Const
Two_PI = PI * 2;
Half_PI = PI / 2;
Var
i : Integer;
vect : TVector3f;
SinCosData : Array of Extended;
Begin
If n < 4 then exit;
If n = 4 then DrawCube; //Ein Zylinder mit 4 Seiten ist ein Würfel - falls es jemanden interessiert *gg*
glEnable(GL_NORMALIZE); //Aktiviere GL_NORMALIZE damit die Normalen nach dem glScale auch die richtige Länge haben
//Berechne die Sinus- und Cosinus-werte einmalig im Voraus
SetLength(SinCosData, (n+1)*2);
for i := 0 to n do
SinCos(i/n * Two_PI, SinCosData[i*2], SinCosData[i*2+1]);
glBegin(GL_QUAD_STRIP);
for i := 0 to n do
begin
vect.x := SinCosData[i*2];
vect.z := SinCosData[i*2+1];
vect.y := 1;
glTexCoord2f(i/n, 0);
glNormal3f(vect.x, 0, vect.z);
glVertex3fv(@vect);
vect.y := -1;
glTexCoord2f(i/n, 1);
glNormal3f(vect.x, 0, vect.z);
glVertex3fv(@vect);
end;
glEnd;
//Zeichnen der oberen Endkappe
glBegin(GL_TRIANGLE_FAN);
vect.y := 1;
glNormal3f(0, 1, 0);
glTexCoord2f(0.5, 0.5);
glVertex3f(0, 1, 0);
for i := 0 to n do
begin
vect.x := SinCosData[i*2];
vect.z := SinCosData[i*2+1];
glTexCoord2f(vect.x*0.5 + 0.5, vect.z*0.5 + 0.5);
glVertex3fv(@vect);
end;
glEnd;
//Zeichnen der unteren Endkappe
glBegin(GL_TRIANGLE_FAN);
vect.y := -1;
glNormal3f(0, -1, 0);
glTexCoord2f(0.5, 0.5);
glVertex3f(0, -1, 0);
for i := n downto 0 do
begin
vect.x := SinCosData[i*2];
vect.z := SinCosData[i*2+1];
glTexCoord2f(0.5 - vect.x*0.5, vect.z*0.5 + 0.5);
glVertex3fv(@vect);
end;
glEnd;
glDisable(GL_NORMALIZE);
End;
Beispiel Aufruf
Einen Zylinder mit der Höhe 3 und dem Radius 4 zeichnet man mit der Prozedur wie folgt:
glPushMatrix; //Sichere die Matrix
glTranslatef(0, 1.5, 0); //Verschiebe den Mittelpunkt des Zylinders an die Position (0 | 1.5 | 0)
glScalef(4, 3 / 2, 4); //Die Höhe wird halbiert, da bei glScale die radien des Objektes stehen sollen
DrawCylinder(16); //Zeichne den Zylinder mit 16 Unterteilungen
glPopMatrix; //Setzte die Matrix auf den Ausgangszustand zurück