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.
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.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Weiterhin sollten Destruktoren immer Destroy heißen und den standarddestruktor überschreiben:
Code:
destructor Destroy; override;
.
Und dann die Klasseninstanzen immer mit Aufruf von Free freigeben.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Sa Aug 18, 2007 18:47 Beiträge: 694 Wohnort: Köln
Programmiersprache: Java
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
_________________ 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"
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.
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.
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:
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.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Und override nicht overload. Und immer Free aufrufen, nicht Destroy.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
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.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Nicht ganz.
Code:
procedureTObject.Free;
begin
// the call via self avoids a warning
if self<>nil then
self.destroy;
end;
... 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:
inherited Destroy;
im eigenen Destruktor erledigt werden. Passenderweise sollte das am Ende geschehen.
Weder Free noch Destroy kümmern sich darum, dass alle Referenzen des Objektes geleert werden.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
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.
Registriert: Do Sep 02, 2004 19:42 Beiträge: 4158
Programmiersprache: FreePascal, C++
Um verwirrung zu vermeiden, solltest du deine Konstenten nicht mit GL_ beginnen lassen.
greetings
_________________ If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung. current projects: ManiacLab; aioxmpp zombofant network • my photostream „Writing code is like writing poetry“ - source unknown
„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb
Mitglieder in diesem Forum: 0 Mitglieder und 6 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.