Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 09, 2025 16:58

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Zylinder beleuchten macht Probleme
BeitragVerfasst: Fr Aug 11, 2006 15:22 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
Hi Leute,
ich habe mir mit
Code:
  1. glBegin(GL_POLYGON);
  2. for i:=1 to 360 do
  3.   begin
  4.     glVertex3f(cos(i),sin(i),0);
  5.     glVertex3f(cos(i),sin(i),2);
  6.   end;
  7. glEnd;

einen Zylinder gebastelt. Allerdings kann man bei dem Zylinder keine Kante erkennen. Nun wollte ich ihn mit Licht beleuchten, sodass der Zylinder auch als solcher erkennbar ist, das hab ich mit dem Code aus dem tutorial gemacht:
Code:
  1. glEnable(GL_LIGHTING);
  2. glEnable(GL_LIGHT0);
  3. glLightf(GL_LIGHT0,GL_POSITION,0);
  4.  

Allerdings wird mien Zylinder dann grau (er war vorher grün) und ich kann immer noch keine Kanten erkennen.
Mache ich einen Denkfehler?

mfg, martin

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 11, 2006 15:27 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Bei Beleuchtungen musst du immer auch noch die Flächennormale miteinbeziehen. Was die Normale genau ist und wie du sie berechnest, kannst du im Wiki nachlesen.

Hast du sie berechnet, gibst du sie einfach per glNormal3f für jedem glVertex3f an. Du würdest dich außerdem leicher tun, wenn du mit Quads oder Triangles anstatt mit GL_POLYGON arbeitest.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 11, 2006 16:23 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
La Boda hat geschrieben:
Bei Beleuchtungen musst du immer auch noch die Flächennormale miteinbeziehen. Was die Normale genau ist und wie du sie berechnest, kannst du im Wiki nachlesen.

Ist es hierbei egal, wie die Orientierung der Normalen ist. Ich meine der Normalenvektor kann doch immer noch 2 Richtungen haben?!

La Boda hat geschrieben:
Hast du sie berechnet, gibst du sie einfach per glNormal3f für jedem glVertex3f an.

Kannst du mir dazu ein Beispiel geben? Mussich jetzt vor jedem Aufruf von glVertex3f erst die entsprechende Normale einstellen, oder wie ist das gemeint?

La Boda hat geschrieben:
Du würdest dich außerdem leicher tun, wenn du mit Quads oder Triangles anstatt mit GL_POLYGON arbeitest.

Tja, aber ich fand es irgendwie kompliziert mit rechteckigen, bzw. dreieckigen Figuren etwas rundes zu erschaffen. Ich weiß wohl, dass ich mich an den Gedanken gewöhnen muss. Gibt es da Code zu, oder sollte ich mir erstmal aus Quad-Streifen einen Zylinder basteln ... Wobei der Deckel und der Boden schwierig werden *grübel*

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Aug 11, 2006 17:58 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Nein, eine Normale hat nur eine Richtung, wie alle Vektoren. Nur die Länge variiert, sollte aber bei Beleuchtungen immer 1 betragen.

glNormal3f wird innerhalb von glBegin...glEnd aufgerufen und bleibt für alle folgenden Vertices aktiv, bis wiederum glNormal3f aufgerufen wird. Für eine Fläche bleibt die Normale natürlich gleich. Deswegen musst man bei Triangles für drei Vertices nur einmal die Normale angeben.
Ein Beispiel:

Code:
  1.  
  2. glBegin(GL_TRIANGLES);
  3.  glNormal3(0, 0, 1);
  4.  glVertex3f(0, 0, 0);
  5.  
  6.  glNormal3(0, 0, 1);
  7.  glVertex3f(1, 0, 0);
  8.  
  9.  glNormal3(0, 0, 1);
  10.  glVertex3f(1, 1, 0);
  11. glEnd;
  12.  


ist gleichbedeutend mit


Code:
  1.  
  2. glBegin(GL_TRIANGLES);
  3.  glNormal3(0, 0, 1);
  4.  glVertex3f(0, 0, 0);
  5.  
  6.  glVertex3f(1, 0, 0);
  7.  
  8.  glVertex3f(1, 1, 0);
  9. glEnd;
  10.  


Letzteres ist natürlich schneller, da du dir ein paar unnütze Funktionsaufrufe sparst.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 13, 2006 14:13 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
Heyho,
war dann mal etwas fleißig und habe mir jetzt aus Quads und Triangles einen Zylinder gebastelt:

Code:
  1. for i:=1 to 360 do
  2. begin
  3.   glBegin(GL_QUADS);
  4.     glVertex3f(cos(i),sin(i),0);
  5.     glVertex3f(cos(i+1),sin(i+1),0);
  6.     glVertex3f(cos(i+1),sin(i+1),2);
  7.     glVertex3f(cos(i),sin(i),2);
  8.   glEnd;
  9.   glBegin(GL_TRIANGLES);
  10.     glVertex3f(cos(i),sin(i),0);
  11.     glVertex3f(cos(i+1),sin(i+1),0);
  12.     glVertex3f(0,0,0);
  13.   glEnd;
  14.   glBegin(GL_TRIANGLES);
  15.     glVertex3f(cos(i),sin(i),2);
  16.     glVertex3f(cos(i+1),sin(i+1),2);
  17.     glVertex3f(0,0,2);
  18.   glEnd;
  19. end;


Wenn ich diesen Zylinder jetzt beleuchten will, muss ich also für jedes Quad und für jedes Triangle einen Normalenvektor bilden, den Einheitsnormalenvektor berechnen und den dann als Normale einstellen?
Und gibt es dazu irgendwelche nützlichen Funktionen oder muss ich mich da selbst bemühen, mit Kreuzprodukt, etc.?

Danke soweit für die Hilfe
mfg, martin

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 13, 2006 14:17 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Naja, die Funktionen sind ja schnell geschrieben, du kannst aber auch die ausm Wiki nehmen.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 13, 2006 14:42 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
Schwachsinn, sorry.

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 13, 2006 15:36 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
So, hab jetzt die ganzen Normalenberechnungen jeweils implementiert, jetzt hab ich noch folgende Probleme:

1) Zeigt er mir den Fehler "invalid enumerant" an. (Suche und Wiki kennen den Fehler nicht)
2) sind irgendwie alle Farben in Grautöne umgewandelt.

Mit meinem Zylinder bin ich eigentlich zufreiden, auch wenn ich damit nur 8fps mache und im Endeffekt ca. 15 Zylinder in einer Szene haben werde, aber naja. Bis hierhin ist es ganz gut gegangen, aber ich hab echt keinen Plan, was jetzt schief läuft, eventuell zeigen die Normalen in die falsche Richtung oder so, dann multipliziere ich sie einfach mal mit -1 ...

Hoffe ihr könnt helfen, danke im Voraus, mfg Martin



Hier mal meine aktuelle Render-Prozedur:

Code:
  1. procedure TMyOpenGL.Render;
  2. var i : integer;
  3.     tmpVector : TVector;
  4. begin
  5.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); //Farb und Tiefenbuffer löschen
  6.  
  7.   glMatrixMode(GL_PROJECTION); //Die OpenGL-Ausgabe manipulieren
  8.   glLoadIdentity; //Die aktuelle Matrix wird mit der Einheitsmatrix gefüllt
  9.   gluPerspective(45.0,zForm.Width/zForm.Height,NeaClipping,FarClipping); //Einstellungen, wie die Szene angezeigt wird
  10.  
  11.   glTranslatef(0,0,-7); //Verschiebt die "Kamera" um 5 Einheiten nach Hinten
  12.  
  13.   glMatrixMode(GL_MODELVIEW); //Die Modelle in der Szene werden manipuliert
  14.   glLoadIdentity; //Die aktuelle Matrix wird mit der Einheitsmatrix gefüllt
  15.  
  16.  
  17.   {* Objekte zeichnen *}
  18.   glEnable(GL_TEXTURE_2D);
  19.   glEnable(GL_LIGHTING);
  20.   glEnable(GL_LIGHT0);
  21.   glLightf(GL_LIGHT0,GL_POSITION,0);
  22.  
  23.   glColor3f(1,1,0);
  24.   glBegin(GL_QUADS);
  25.     glTexCoord2f(0,0); glVertex3f(-2,-2,0);
  26.     glTexCoord2f(0,1); glVertex3f(2,-2,0);
  27.     glTexCoord2f(1,1); glVertex3f(2,2,0);
  28.     glTexCoord2f(1,0); glVertex3f(-2,2,0);
  29.   glEnd;
  30.  
  31.   glDisable(GL_TEXTURE_2D);
  32.  
  33.   gltranslatef(0,0,2);
  34.   inc(rotation);
  35.   glrotatef(rotation,0,1,0);
  36.  
  37.  
  38.   glColor3f(0,1,0);
  39.     for i:=1 to 360 do
  40.       begin
  41.         tmpVector := getNormal(makeTriangle(MakeVector(cos(i),sin(i),0),
  42.                                             MakeVector(cos(i+1),sin(i+1),0),
  43.                                             MakeVector(cos(i+1),sin(i+1),2)));
  44.         glNormal3f(tmpVector.x,tmpVector.Y,tmpVector.z);
  45.         glBegin(GL_QUADS);
  46.           glVertex3f(cos(i),sin(i),0);
  47.           glVertex3f(cos(i+1),sin(i+1),0);
  48.           glVertex3f(cos(i+1),sin(i+1),2);
  49.           glVertex3f(cos(i),sin(i),2);
  50.         glEnd;
  51.         tmpVector := getNormal(makeTriangle(MakeVector(cos(i),sin(i),0),
  52.                                             MakeVector(cos(i+1),sin(i+1),0),
  53.                                             MakeVector(0,0,0)));
  54.         glNormal3f(tmpVector.x,tmpVector.Y,tmpVector.z);
  55.         glBegin(GL_TRIANGLES);
  56.           glVertex3f(cos(i),sin(i),0);
  57.           glVertex3f(cos(i+1),sin(i+1),0);
  58.           glVertex3f(0,0,0);
  59.         glEnd;
  60.         tmpVector := getNormal(makeTriangle(MakeVector(cos(i),sin(i),2),
  61.                                             MakeVector(cos(i+1),sin(i+1),2),
  62.                                             MakeVector(0,0,2)));
  63.         glNormal3f(tmpVector.x,tmpVector.Y,tmpVector.z);
  64.         glBegin(GL_TRIANGLES);
  65.           glVertex3f(cos(i),sin(i),2);
  66.           glVertex3f(cos(i+1),sin(i+1),2);
  67.           glVertex3f(0,0,2);
  68.         glEnd;
  69.       end;
  70.  
  71.  
  72.   SwapBuffers(DC);  //Den Inhalt des Framebuffers auf den Bildschirm bringen (Front und Backbuffer tauschen)
  73. end;

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 13, 2006 15:38 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo,

Zylinder kannst du auch ganz leicht mit GLU erstellen.
Mit gluQuadricNormals lassen sich dann die Normalen generieren ;)

Viele Grüße
dj3hut1


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Aug 14, 2006 17:20 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Naja vom Gebrauch der betagten glu würde ich mal abraten, auch wenn sie in diesem Fall vielleicht schneller läuft.

Folgende Sachen fallen mir in dienem Code auf:
Du zeichnest komischerweise alle Flächen einmal mit GL_QUADS und dann mit zwei GL_TRIANGLES nochmal:
Code:
  1. glBegin(GL_QUADS);
  2.           glVertex3f(cos(i),sin(i),0);
  3.           glVertex3f(cos(i+1),sin(i+1),0);
  4.           glVertex3f(cos(i+1),sin(i+1),2);
  5.           glVertex3f(cos(i),sin(i),2);
  6.         glEnd;
  7.         tmpVector := getNormal(makeTriangle(MakeVector(cos(i),sin(i),0),
  8.                                             MakeVector(cos(i+1),sin(i+1),0),
  9.                                             MakeVector(0,0,0)));
  10.         glNormal3f(tmpVector.x,tmpVector.Y,tmpVector.z);
  11.         glBegin(GL_TRIANGLES);
  12.           glVertex3f(cos(i),sin(i),0);
  13.           glVertex3f(cos(i+1),sin(i+1),0);
  14.           glVertex3f(0,0,0);
  15.         glEnd;
  16.         tmpVector := getNormal(makeTriangle(MakeVector(cos(i),sin(i),2),
  17.                                             MakeVector(cos(i+1),sin(i+1),2),
  18.                                             MakeVector(0,0,2)));
  19.         glNormal3f(tmpVector.x,tmpVector.Y,tmpVector.z);
  20.         glBegin(GL_TRIANGLES);
  21.           glVertex3f(cos(i),sin(i),2);
  22.           glVertex3f(cos(i+1),sin(i+1),2);
  23.           glVertex3f(0,0,2);
  24.         glEnd;
  25.       end;


Das macht aber wenig Sinn, weil die Flächen dann genau die gleich sind. Dass die Beleuchtung nicht wie gewünscht hinhaut, kann entweder daran liegen, dass die Lichtquelle sich an einer falschen Position (zB innerhalb des Zylinders) befindet oder die Normalen in die falsche Richtungzeigen. Letzteres kann daher kommen, dass du deine Vektoren der Vertices in der falschen Reihenfolge bei der Normalenberechnung verwendest.

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 16, 2006 07:23 
Offline
DGL Member

Registriert: Di Feb 10, 2004 14:55
Beiträge: 28
Wohnort: Gelsenkirchen
So, hab jetzt wieder bissel Zeit an dem Projekt zu arbeiten.
La Boda hat geschrieben:
Folgende Sachen fallen mir in dienem Code auf:
Du zeichnest komischerweise alle Flächen einmal mit GL_QUADS und dann mit zwei GL_TRIANGLES nochmal:
Das macht aber wenig Sinn, weil die Flächen dann genau die gleich sind.

Die Quads bilden den Zylindermantel, die Triangles bilden den Deckel und den Boden, sind in so fern schon wichtig.

La Boda hat geschrieben:
Dass die Beleuchtung nicht wie gewünscht hinhaut, kann entweder daran liegen, dass die Lichtquelle sich an einer falschen Position (zB innerhalb des Zylinders) befindet oder die Normalen in die falsche Richtungzeigen. Letzteres kann daher kommen, dass du deine Vektoren der Vertices in der falschen Reihenfolge bei der Normalenberechnung verwendest.

Ich hab jetzt einfach mal an einem Viereck im Hintergrund das Ganze ausprobiert. Ich glaube, dass mein Licht an einer falschen Position ist, bzw. in eine falsche Richtung leuchtet oder so. Aber sollte bei einem Aufruf von
Code:
  1. glEnable(GL_LIGHTING);
  2. glEnable(GL_LIGHT0);
  3. glLightf(GL_LIGHT0,GL_POSITION,0);

nicht so eine Art "Sonne" erstellt werden, die alles beleuchtet? Oder muss ich mir die SOnne auch noch irgendwohin verschieben?

_________________
Behaupten ist sicherer als Beweisen.
Meine OGL-Projekte


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 16, 2006 09:55 
Offline
DGL Member
Benutzeravatar

Registriert: Mi Jul 17, 2002 12:07
Beiträge: 976
Wohnort: Tübingen
Wie du die Position der Lichtquelle setzt, kannst du in diesem Tutorial nachlesen: Tutoiral lektion8


Mir ist jetzt noch aufgefallen, an was die Performanceeinbußen liegen könnten. Deine Funktion getNormal(...) berechnet die Normalen. Höchstwahrscheinlich normierst die sie auch gleich in dieser Funktion, bringst sie also auf die Länge 1. Dazu ist es ja nötig, dass die Wurzel gezogen wird. Und DAS ist wirklich sehr anspruchsvoll für die CPU. Du müsstest pro Frame 360 * 3 = 1080 mal die Wurzel ziehen, und bei sowas tut sich die CPU sehr hart. Du solltest also die Normalen entweder nur beim Initialisieren berechnen und dann zB in ein Array abspeichern oder du arbeitest mit Displaylisten

_________________
"Du musst ein Schwein sein in dieser Welt, sangen die Prinzen, das ist so 1.0. Du musst auf YouTube zeigen, dass dir dein Schweinsein gefällt, das ist leuchtendes, echtes Web 2.0."
- Hal Faber

Meine Homepage: http://laboda.delphigl.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 16, 2006 17:02 
Offline
DGL Member

Registriert: So Feb 19, 2006 23:46
Beiträge: 55
Wenn man die Normalen selbst berechnet, braucht man sie aber nicht unbedingt zu normalisieren. Wenn GL_NORMALIZE mit glEnable eingeschaltet wird, erledigt die OpenGL-Implementation das, was dann eventuell hardwareeschleunigt ist.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Aug 16, 2006 17:11 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 27, 2005 12:44
Beiträge: 393
Wohnort: Berlin
Programmiersprache: Java, C++, Groovy
Hallo,

bei statischen Objekten würd ich generell mit Displaylisten arbeiten.
Von daher ist die Wurzelberechnung nicht weiter schlimm, da in der Liste nur das berechnete Ergebnis abgespeichert wird.

und was GLU betrifft : die Bibliothek (welche ja nichts weiter macht als bestehende OpenGL-Befehle zusammenzufassen) mag zwar nicht mehr auf dem allerneuesten Stand zu sein, kann einem aber ab und zu viel (überflüssige) Arbeit abnehmen ;)

Viele Grüße
dj3hut1


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 14 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 9 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 15 Queries | GZIP : On ]