- destructor Destroy; override;
DGL https://delphigl.com/forum/ |
|
Shader und Shaderlist https://delphigl.com/forum/viewtopic.php?f=20&t=8497 |
Seite 1 von 2 |
Autor: | mori [ Di Jun 30, 2009 15:04 ] |
Betreff des Beitrags: | Shader und Shaderlist |
Hi, ich habe mich vor kurzem an ein Projekt gesetzt, weil es mir aber zu umständlich war für jeden Shader extra Code zu schreiben, habe ich mir eine Unit erstellt die die Klassen TShader (einzelner Shader) und TShaderList enthält. Ich poste die Unit einfach mal, vielleicht kann sie jemand gebrauchen. PS: Die Unit ist warscheinlich nicht Fehlerfrei, für Tipps währe ich dankbar. Code:
|
Autor: | Markus [ Di Jun 30, 2009 18:35 ] |
Betreff des Beitrags: | |
Ich hab nur mal schnell drüber geschaut - du solltest deine Free()-Methode umbenennen, weil es die in TObject schon gibt. Das könnte unter Umständen verwirrend sein. |
Autor: | Lord Horazont [ Di Jun 30, 2009 18:50 ] |
Betreff des Beitrags: | |
Weiterhin sollten Destruktoren immer Destroy heißen und den standarddestruktor überschreiben: Code:
Und dann die Klasseninstanzen immer mit Aufruf von Free freigeben. greetings |
Autor: | damadmax [ Di Jun 30, 2009 22:56 ] |
Betreff des Beitrags: | |
Zitat: ShaderCount:Integer;
Kannst du dir auch sparen, da TList eine solche Eigenschaft bereits hat. In meiner Unit hab ich eine abstrakte Klasse für alle Shadertypen benutzt. Davon wird dann jeweils Fragment, Vertex oder auch Geometry (wenn ich es denn mal einbaue) abgeleitet. Die Handles auf die einzelnen Shaderobjekte brauchen/sollten auch nicht public sein. Die braucht man draussen sowieso nicht. Falls doch -warum auch immer- würde ich diese in Funktionen kapseln. Gruß damadmax |
Autor: | Schläfer [ Mi Jul 01, 2009 16:05 ] |
Betreff des Beitrags: | |
Du übergibts der Funktion "TShader.CreateShader" die Variablen "VertexShaderObject" und "FragmentShaderObject", die aber immer NULL sein sollten. Besonders am Anfang, falls man sie nicht selbst setzt. Abgesehen davon werden die Werte gleich mit "VertexShader := glCreateShader(GL_VERTEX_SHADER);" (Zeile 162) bzw. "FragmentShader := glCreateShader(GL_FRAGMENT_SHADER);" (Zeile 172) überschrieben. Dann werden sie wieder freigegeben ("glDeleteShader") wodurch sie wieder NULL sind. Selbst wenn die Paramter als "var" deklariert wären, würden sie keine brauchbaren Informationen enthalten. Was mir auch noch gerade auffällt: "ProgramObject" ist auch kein "var"-Paramter. Darum bleibt "TShader.ProgramObject" auch immer NULL. Mal ganz davon abgesehen das es sinnlos ist das als Paramter zu übergeben, weil die Funktion auch so darauf zugreifen kann. Und zur Form: Ich denke ich das die Handles nicht "public" sein sollten, sonst ändert die noch einer. Es ist sicherlich gut so wenig wie möglich, aber so viel wie nötig, in den Public-Teil zu packen. Also kann da meiner Meinung nach die Funktionen "glSlang_GetInfoLog" raus. Hm, der constructor in Zeile 29 ist relativ sinnlos. Der erstellt nur die Stringlisten. Die du dann mit SetShaderCode füllen musst. Und dann muss noch der Shader mit CreateShader erzeugt werden. Das "Create" in der Zeile darüber macht aber all das selbst. Wenn man mit "SetShaderCode" den Code aus mehreren Teilen zusammensetzen könnte, hätte das vielleicht noch einen Sinn, aber da der vorherige Teil immer gelöscht wird, wird man das wohl nie benutzen. Und wenn man das Create weglässt, können auch "SetShaderCode" und "CreateShader" aus dem "public"-Bereich raus. |
Autor: | mori [ Mi Jul 01, 2009 17:08 ] |
Betreff des Beitrags: | |
Zitat: Und wenn man das Create weglässt, können auch "SetShaderCode" und "CreateShader" aus dem "public"-Bereich raus.
Ich hatte Create deshalb getrennt und in die funktionen in den public-Bereich verschoben, falls man den Shader nachträglich nochmal ändern möchte z.B zum Testen von Shadern, die direkt eingetippt werden ect. |
Autor: | mori [ Mi Jul 01, 2009 17:29 ] |
Betreff des Beitrags: | |
Hi, ich habe eben noch einen großen Fehler behoben, bis jetzt sind die Shder nicht geladen worden ![]() Jetzt funktioniert aber alles, ich habe die meisten Tipps umgesetzt. Hier die zumindest richtig funktionierende Unit: Code:
|
Autor: | Schläfer [ Mi Jul 01, 2009 19:16 ] |
Betreff des Beitrags: | |
mori hat geschrieben: Zitat: Und wenn man das Create weglässt, können auch "SetShaderCode" und "CreateShader" aus dem "public"-Bereich raus. Ich hatte Create deshalb getrennt und in die funktionen in den public-Bereich verschoben, falls man den Shader nachträglich nochmal ändern möchte z.B zum Testen von Shadern, die direkt eingetippt werden ect. OK, das ist natürlich ein Grund. Man könnte auch den Shader mit Free löschen und einen neuen erstellen, aber das ist dann nicht so günstig wenn man zwischendurch auf den zugreifen will. Das "UseStep" soll wohl dafür sorgen das alles in der richtigen Reihenfolge gemacht wird? Hast du auch daran gedacht das alte Handle freizugeben, sonst bleiben die alten Shader noch im Speicher. In "CreateShader" hab ich nichts gefunden, hab aber grad nicht die Zeit alles nochmal durchzuschauen. |
Autor: | Markus [ Do Jul 02, 2009 09:57 ] |
Betreff des Beitrags: | |
Jetzt hast du Free() in Destroy() umbenannt... Destroy() ist normalerweise der Destruktor und keine Prozedur, das solltest du ändern. |
Autor: | Lord Horazont [ Do Jul 02, 2009 12:22 ] |
Betreff des Beitrags: | |
Und override nicht overload. Und immer Free aufrufen, nicht Destroy. greetings |
Autor: | mori [ Do Jul 02, 2009 15:18 ] |
Betreff des Beitrags: | |
Zitat: Jetzt hast du Free() in Destroy() umbenannt... Destroy() ist normalerweise der Destruktor und keine Prozedur, das solltest du ändern. Ja das mit dem Destructor ist mir auch kurz nachdem ich es gepostet habe aufgefallen Zitat: Und override nicht overload. Das mit dem overload habe ich auch erst nachdem ich es gepostet hatte gesehen ist jetzt aber korrigiert. Zitat: Und immer Free aufrufen, nicht Destroy.
Was heißt das jetzt, soll ich Destroy überschreiben aber Free aufrufen? |
Autor: | Sellmann [ Do Jul 02, 2009 15:46 ] |
Betreff des Beitrags: | |
Free ist eine procedure die Destroy aufruft und allen betroffenen Objekten bescheid gibt, dass dein Objekt nicht mehr existiert. Außerdem werden durch Free alle weiteren Funktionen aufgerufen, die für die allgemeine Objektstruktur notwendig sind um ein Objekt sauber aus dem Arbeitsspeicher zu entfernen. Nicht zu vergessen ist, dass ggf. der Destructor der Mutterklasse ausgeführt werden muss. Das sind alles Dinge die "Destroy" nicht von sich aus macht, Free schon. |
Autor: | Lord Horazont [ Do Jul 02, 2009 16:42 ] |
Betreff des Beitrags: | |
Nicht ganz. Code:
... Um mal kurz aus der objpas.inc zu zitieren [zur besseren Lesbarkeit leicht abgeändert]. Free tut also nichts weiter als vorher zu prüfen, ob man nicht gerade versucht, einen nil-Pointer freizugeben. Es gehört einfach zum guten Stil, Free aufzurufen anstatt Destroy. Der aufruf von Destroy wird dann von Free erledigt. Das Aufrufen der Destruktoren der Vorfahrenklassen muss durch ein Code:
Weder Free noch Destroy kümmern sich darum, dass alle Referenzen des Objektes geleert werden. greetings |
Autor: | mori [ Mi Jul 08, 2009 13:15 ] |
Betreff des Beitrags: | |
Hi, hier ist nochmal eine neue Version, ich habe die Fehlerbehandlung geändert, und ein paar neue Funktionen hinzugefügt. Mit TShaderErrors kann man jetzt auch herausfinden was den Fehler verursacht hat. Code:
|
Autor: | Lord Horazont [ Mi Jul 08, 2009 13:44 ] |
Betreff des Beitrags: | |
Um verwirrung zu vermeiden, solltest du deine Konstenten nicht mit GL_ beginnen lassen. greetings |
Seite 1 von 2 | Alle Zeiten sind UTC + 1 Stunde |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |