Registriert: Do Jun 18, 2009 07:17 Beiträge: 44 Wohnort: Gießen/Hessen
Ich versuche gerade eine SkyBox so zu erweitern das man aus verschiedenen Unterverzeichnissen quasi "On The Fly" laden kann.
Um das zu realisieren habe ich ein Klassen-Typen geschrieben:
Code:
TOGLPictureBox =class(TObject)
Folder:AnsiString;{ the absolute image folder }
Title:AnsiString;{ the last folder of the image folder }
DisplayID: TGLuint;{ the display ID }
SkyBoxTexture :Array[0..5]of TGLBmp;{ the loaded textures }
end;
der alle Daten auf dem Heap aufnehmen soll, das Laden funktioniert auch einwandfrei, in einer Liste werden die geladenen Verzeichnisse angezeigt. Aber auf der Oberfläche wird nichts anzeigt.
Ich gehe wie folgt vor:
Code:
procedure TGLForm.LoadSkyBoxFromFolder;
var
Box: TOGLPictureBox;
I:Integer;
FolderList: TStrings;
begin
FolderList := TStringList.Create;{ create the img folder list}
FindAllImageFolders(FolderList);{ fill the img folder list, contains
now all application sub folders }
for I :=0to FolderList.Count-1do{ iterate through the folders }
begin
Box := TOGLPictureBox.Create;{ create the PictureBox data holder }
Box.Folder:= FolderList[I];
Box.Title:=ExtractFileName(
FolderList[I]);{ extract the last folder name }
LoadSkyBox(Box);{ Load the textures into SkyBoxTexture array
calls the function GenerateSkyBox -> create
the real box and bind the textures}
if I =0then
FActiveListID := Box.DisplayID;{ set the first display list active }
ListBox1.Items.AddObject({ add the PictureBox obejct to ListBox }
// As the Skybox will fill the entire screen, we will only have to clear
// the depth buffer and not the color buffer
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
glRotatef(xrot,1,0,0);
glRotatef(yrot,0,1,0);
// Call the Displaylist of our Skybox
glCallList(FActiveListID);
SwapBuffers(FDC);
end;
Ich muss dazusagen, dass das Grundgerüst aus dem Tutorial SkyBoxen stammt, ich habe lediglich die Funktionssignaturen an meine Bedürfnisse angepasst, und ein paar kleine Änderungen vorgenommen.
Ich vermute das man die Texturen nicht dauerhaft an glGenLists/glNewList binden kann, daher ist dann auch keine Textur aktiv die Angezeigt werden kann. Ich habe auch keine Ausgabe, wenn nur ein Unterverzeichnis angegeben habe das Ergebnis ist das Gleiche.
Tut mir leid soviel Source-Code zu päsentieren, aber ich glaube ich habe da ein echtes Verständisproblem mit den DisplayListen.
_________________ Gruß Andreas (aka DeepCopy) - Sic Luceat Lux
Classified Directive: initialization write in function for finalization, repeat until public case uses begin, if not case type as default, var in virtual override for while, in case of class type type asm until read begin.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
Code:
Box.DisplayID := glGenLists(1);
glNewList(SkyBox, GL_COMPILE);
sollte auch so aussehen:
Code:
Box.DisplayID := glGenLists(1);
glNewList(Box.DisplayID, GL_COMPILE);
OpenGL will ja auch schliesslich wissen welche Liste erstellt werden soll.
Des weiteren fehlt ein 'glEndList'. Welches du aber wahrscheinlich weggekürzt hast.
Allerdings würde ich auch das Laden von Texturen oder Objekten vom Erstellen selbiger trennen.
Eine Skybox ist schliesslich nichts anderes als ein Würfel, nur dass er andersrum gezeichnet werden muss, wegen Backfaceculling.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Do Jun 18, 2009 07:17 Beiträge: 44 Wohnort: Gießen/Hessen
Du bist mein persönlicher Held !
Zitat:
sollte auch so aussehen:
Code:
Box.DisplayID := glGenLists(1);
glNewList(Box.DisplayID, GL_COMPILE);
Daran war ich fast am verzweifeln - du hast ein sehr gutes Auge - , Danke damadmax!
Zitat:
Allerdings würde ich auch das Laden von Texturen oder Objekten vom Erstellen selbiger trennen. Eine Skybox ist schliesslich nichts anderes als ein Würfel, nur dass er andersrum gezeichnet werden muss, wegen Backfaceculling.
Das habe ich nicht verstanden, wie meinst du das? - Und was hat das mit Backfaceculling zu tun?
_________________ Gruß Andreas (aka DeepCopy) - Sic Luceat Lux
Classified Directive: initialization write in function for finalization, repeat until public case uses begin, if not case type as default, var in virtual override for while, in case of class type type asm until read begin.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Er meint, dass es ein Unterschied ist, ob man den Würfel von innen sieht (aka "SkyBox") oder ob man den Würfel von außen sieht.
Würfel von innen sichtbar: Alle Quads müssen nach innen zeigen (das hat etwas mit dem Umlaufsinn ihrer Eckpunkte zu tun)
Würfel von außen sichtbar: Alle Quads müssen nach außen zeigen.
Daraus folgt: wenn Du eine Skybox von außen siehst und gleichzeitig Backface-Culling eingeschaltet hast, ist er unsichtbar, weil der ganze Würfel dem Backface Culling zum Opfer fällt und daher nicht gezeichnet wird.
Und er meint, dass man das Laden der Strukturen vom Erstellen der Listen trennen sollte. Das betrifft Dich eigentlich nur, wenn Du vorhast, etwas Komplizierters zu bauen, denn dann werden auch andere Dinge wichtig, wie zum Beispiel Übersichtlichkeit des Codes und Performance.
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
@Traude: Genau. So schön kann ich einfach nicht formulieren. Danke
Auf die Zeichenrichtung sollte man von anfang an achten. Falls man später erst das Culling aktiviert, könnte das sehr unschön aussehen und auch eine Heidenarbeiten sein das überall in den Tiefen des Quellcodes zu finden und zu korrigieren.
Noch was zu den Quads. Ich würde Dreiecke bevorzugen. Und diese nicht direkt in eine Displayliste ausgeben sondern eine gesonderte (geerbte) (z.b.)'buildObject' Funktion verwenden, die die Liste erstellt. Während der Erstellung deines Objekts packst du alle Daten (Vertex, Texturkoordinaten, Farbe, etc.pp) in Arrays und erst die buildObject Funktion erstellt die Displayliste. Somit hat man zum einen weniger glBegins und glEnd und zum anderen lässt es sich später sehr einfach auf VBOs umstellen.
_________________ Es werde Licht. glEnable(GL_LIGHTING); Und es ward Licht.
Zitat aus einem Java Buch: "C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off"
Registriert: Do Jun 18, 2009 07:17 Beiträge: 44 Wohnort: Gießen/Hessen
Ok, eine menge Hinweise... danke erstmal an Euch!
Also eins nach dem Anderen:
Zitat:
Und er meint, dass man das Laden der Strukturen vom Erstellen der Listen trennen sollte. Das betrifft Dich eigentlich nur, wenn Du vorhast, etwas Komplizierters zu bauen, denn dann werden auch andere Dinge wichtig, wie zum Beispiel Übersichtlichkeit des Codes und Performance.
@Traude: Kannst du mir dazu ein Praxisbeispiel nennen?
Zitat:
Während der Erstellung deines Objekts packst du alle Daten (Vertex, Texturkoordinaten, Farbe, etc.pp) in Arrays und erst die buildObject Funktion erstellt die Displayliste.
@damadmax: Also etwa so:
Code:
type
TOpenGLObject =class(TObject)
private
FIsBuildObject:Boolean;
FPosition: TVertex3f;
FRotation: TMatrix4f;
public
procedure buildObject;abstract;
procedure drawObject;virtual;
end;
TBaum =class(TOpenGLObject)
private
FBaumTexture:Arrayof TGLBitmap;
FBaumTextureCoords:Arrayof TVertex2f;
FBaumObject:Arrayof TVertex4f;
public
procedure buildObject;override;
procedure drawObject;override;
end;
implementation
procedure TOpenGLObject.drawObject;virtual;
begin
ifnot FIsBuildObject then buildObject;
end;
Meine Frage nun, wann soll buildObject aufgerufen werden? Vor dem Aufruf von drawObject, oder beim Aufruf von drawObject wie oben gezeigt?
Ich denke wann drawObject aufgerufen wird ist schon klar, immer in der Render procedure.
Zitat:
Somit hat man zum einen weniger glBegins und glEnd und zum anderen lässt es sich später sehr einfach auf VBOs umstellen.
Wieso habe ich weniger glBegin und glEnd? Die Anzahl von glBegin und glEnd in der Displayliste sind doch gleich, oder? Das mit den VBO's hab ich mir mal angesehen, aber noch nicht vollständig verstanden, es soll wohl die Vorzüge von VertexArrays mit Displaylisten vereinen.
Welchen Vorteil hätte ich denn konkret davon?
_________________ Gruß Andreas (aka DeepCopy) - Sic Luceat Lux
Classified Directive: initialization write in function for finalization, repeat until public case uses begin, if not case type as default, var in virtual override for while, in case of class type type asm until read begin.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Traude hat geschrieben:
Und er meint, dass man das Laden der Strukturen vom Erstellen der Listen trennen sollte. Das betrifft Dich eigentlich nur, wenn Du vorhast, etwas Komplizierters zu bauen, denn dann werden auch andere Dinge wichtig, wie zum Beispiel Übersichtlichkeit des Codes und Performance.
DeepCopy hat geschrieben:
@Traude: Kannst du mir dazu ein Praxisbeispiel nennen?
Das Laden der Strukturen unterscheidet sich vom Erstellen der Listen dadurch, dass man beim Listen erstellen einen Rendering Context braucht und beim Laden von der Platte nicht. Dadurch ergibt sich die Möglichkeit, das Laden von Platte mittels Threads zu beschleunigen, was bei Listenerstellen nicht geht, denn man kann nicht auf OpenGL-Befehle aus einem anderen Thread zugreifen.
Oder Du möchtest später - wie oben schon erwähnt wurde - alles in ein VBO laden, dann müsstest Du warten, bis der Ladevorgang für alle Objekte fertig ist, damit man sie alle zusammen an die Grafikkarte schicken kann.
Das sind beides gute Argumente dafür, das Laden in den Hauptspeicher vom Laden in den Grafikspeicher nicht in der gleichen Prozedur zu erledigen.
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.