Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
wir sind dabei einen Teil unserer Engine umzubauen und haben uns dazu entschlossen euch daran teilhaben zu lassen. Das Ganze ist ein PreCompiler für GLSL, mit dessen Hilfe man über IFDEF und INCLUDE dynamischen Shader-Code zusammen bauen kann. Zumindest war es das bis jetzt. Das hat zwar bis jetzt ganz gut funktioniert, aber hier und da sind wir an einige Grenzen gestoßen. Deshalb haben wir uns entschlossen den Teil etwas aufzubohren. Daraus ist eine Art Klassenstruktur für GLSL-Shader entstanden, die ich im folgenden etwas genauer beschreiben will.
Was bedeutet das nun alles? Compiler Direktiven haben prizipiell die Form {$IRGENDWAS ...}. Folgende Direktiven gibt es:
{$INCLUDE} - fügt dem Code-Baum eine weitere Shader-Datei hinzu
{$CLASS 'ClassName' [$EXTENDS 'BaseClass' ...]} - definiert eine Klasse mit einem bestimmten Namen und ggf. mehreren Basis-Klassen
{$DEFINE 'Name' 'Value'} - erzeugt eine Art Konstante, die nur dem PreCompiler bekannt ist und dient mehr oder weniger nur der Übersicht und um Magic Numbers zu umgehen
{$ATTRIB 'Name' 'Type' ['Initial Value']} - definiert ein Attribut, welches durch die Applikation gesetzt werden kann. Über diese Attribute kommuniziert die Applikation mit dem PreCompiler und legt indirekt fest welche Code-Teile im finalen Shader eingepflegt werden
{$FUNC 'Name' 'ReturnType' ['ParameterName' 'ParameterType' ...]} - definiert eine Funktion, welche auch später eine Funktion im Shader repräsentiert. Funktionen sind prizipiell immer virtuell und können von Kindklassen überschrieben werden.
{$UNIFORM 'Name' 'Type'} - definiert eine uniform Variable
{$VARYING 'Name' 'Type'} - definiert eine varying Variable
{$VAR 'Name' 'Type' ['Initial Value']} - definiert eine globale Shader Variable (eine Art Member-Variable)
{$IF 'logical statement'} - einfache Code-Verzweigung, hier werden die Werte der Klassen-Attribute ausgewertet
{$CALL 'FunctionName' ['Parameter' ...]} - ruft eine Funktion auf
{$MAIN} - spezielle Funktion die in einer Klassen-Hierarchie mindestens von einer Klasse definiert werden muss
(Parameter in eckigen Klammern sind optional)
Wie arbeitet das Alles? Zunächste wird die Datei geladen und interpretiert. Anschleißened kann Applikation verschiedene Einstellungen am Shader ändern. Beim generieren des Codes wird in der $MAIN-Funktion gestartet und sich von dort aus duch den Code-Baum gearbeitet. Code-Teile die nicht benötigt werden, werden nicht im finalen Shader-Code eingefügt. Das gilt ebenso für Variabel, Uniforms, Varyings und und und ...
Das ist ersteinmal die grobe Idee dazu. Bis jetzt ist noch nix implementiert. Was haltet ihr davon? Was findet ihr gut? Was würdet ihr anders / besser machen? Wir würden das gern mit euch diskutieren. Vlt will das System ja auch der ein oder andere für seine Projekte nutzen?
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
hat alles bisl länger gedauert als geplant, aber jetzt steht die Funktionalität soweit, das man mal was zeigen kann. Deshalb gibts jetzt ein paar einfache Beispiele, wie wir das ganze System nutzen wollen. Prinzipiell kann man den PreCompiler auf 2 Arten nutzen:
prozedural: mit simplen Methoden und Include-Files (ähnlich wie man das von C kennt)
Pseudo-Klassen: mit virtuellen Methoden die von einer übergeordneten Klasse überschrieben werden können
Beispiel für simple Include-Files Folgendes Beispiel beinhaltet 2 Datein:
Simple.frag: enthält die main und soll einfach die Farbe eines Fragments berechnen
Color.frag: enthält die eigentlichen Routinen zur Berechnung der Farbe und wird von Simple.frag eingefügt und aufgerufen. Weiterhin gibt es ein Attribut, welches bestimmt wie die Farbe berechnet werden soll (konstant oder aus einer Textur)
Color.frag:
Code:
{$ATTRIB UseColorMap 'false'}
{$IF $NOT UseColorMap}
constvec4 COLOR =vec4(1.0,0.75,0.25,1.0);
{$END}
{$FUNC 'vec4' GetColor}
{$IF UseColorMap}
{$UNIFORM 'sampler2D' uColorMap}
returntexture2D(uColorMap,gl_TexCoord[0].st);
{$ELSE}
return COLOR;
{$END}
{$END}
Simple.frag:
Code:
{$INCLUDE 'Color.frag'}
{$MAIN}
gl_FragColor={$CALL GetColor};
{$END}
Programm-Code:
Code:
var ShaderFile: TengShaderFile;
var ShaderClass: IengShaderPartClass;
var Code:String;
ShaderFile := TengShaderFile.Create;
try
ShaderFile.LoadFromFile('Simple.frag');
ShaderClass := ShaderFile.Generator[''];// empty class name = file/global class
Beispiel für Klassen Jetzt wird's etwas komplizierter. Im Beispiel gibts es (ähnlich wie oben) 2 Klassen:
Simple: beinhaltet (wie oben) die main und berechnet die Farbe eines Fragments. Sie ist von der Color-Klasse abgeleitet und greift in die Berechnung der Farbe ein (siehe Simple.GetColor)
Color: die Color-Klasse berechnet (ebenfalls wie oben) die Farbe eines Fragments. Jenachdem welchen Wert das Attribut hat wird die Farbe wieder konstant gesetzt, oder aus einer Textur geladen
Zum Schluss gibt es noch einmal eine aktualisierte Liste mit allen PreCompiler-Tokens, da sich dort auch das ein oder andere geändert hat oder neu dazu gekommen ist.
[] - bedeutet optional [X ...] - kann beliebig oft wiederholt werden 'Value' - sind Werte die in Variablen gesetzt werden können, diese Werte werden 1 zu 1 übernommen, es erfolgt keine Prüfung
Token:
{$CLASS ClassName [$EXTENDS BaseClass [...]]} Definiert eine Klasse mit den Vorfahren "BaseClass"
{$INHERITED [BaseClass] [Parameter, ...]} Ruft eine Methode der Basis-Klasse auf. Bei Mehrdeutigkeit muss der Name der Basis-Klasse angegeben werden. Wenn die Paramter nicht angegeben werden, dann werden die Parameter 1 zu 1 übergeben
{$INCLUDE 'Filename'} Fügt eine Quell-Datei in den Code-Baum ein
{$META 'Fuu' 'Bar'} Definiert Meta-Daten für den Shader (kann vom Programm ausgelesen werden)
{$META $VERSION 'version'} Spezieller Wert für Meta-Daten. Gibt die minimale Shader-Version an.
{$META $EXTENSION 'GL_ARB_geometry_shader4' 'enable'} Spezieller Wert für Meta-Daten. Aktiviert eine Extention.
{$META $LAYOUT '(line_strip, max_vertices = 6) out'} Spezieller Wert für Meta-Daten. Setzt das Layout eines Geometry Shaders.
{$DEFINE TEST_DEFINE '0'} Definiert eine PreCompiler Konstante
{$ATTRIB InvertRoughmap ['Initial Value' | DefineName]} Definiert ein Attribute.
{$ECHO Identifier} Gibt den Wert eines Attributes oder eines Defines aus (schreibt den Wert in den ShaderCode).
{$VAR 'Type' Name ['Initial Value']} Definiert eine Member Variable. Wird dann im ShaderCode zu einer globalen Variable.
{$VARYING 'Type' Name} Definiert ein Varying.
{$UNIFORM 'Type' uShadowMap} Definiert ein Uniform.
{$CALL MethodeName['Parameter']} Ruft eine Methode auf.
{$PROC MethodeName['ParameterType' 'ParameterName' ...] [$INLINE]} Code... {$END} {$MAIN} Definiert eine neue Prozedur.
{$FUND 'ReturnType' 'MethodeName' ['ParameterType' 'ParameterName'] [$INLINE]} Code... {$END} Definiert eine neue Funktion.
Soweit erstma zum aktuellen Stand. Die Unit zum selbst probieren gibts es im Laufe der folgenden Woche. Wir müssen uns erstmal überlegen wie genau wie das zur Verfügung stellen und wie wir das dann pflegen.
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
wieder mit etwas Verspätung heute das Update mit Download & Co (siehe erster Post). Wir haben den glslPreCompiler mit in den OpenGLCore aufgenommen (heißt dort uglcShaderFile). Das haben wir so gemacht, da wir den Code so besser verwalten können und nicht für jede Datei ein extra Repo/Versionnierung haben. Der Thread hier bleibt trotzdem und wird auch in Zukunft alles was mit dem PreCompiler zu tun hat beinhalten.
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey,
bei der Unit haben noch einige Abhängigkeiten gefehlt. Ich hab versucht die aufzulösen, aber das ist zu sehr verstrickt. Deshalb gibts die Units jetzt mit zum Download im ersten Post. Das passt jetzt auch nicht mehr richtig in den LazOpenGLCore rein, deshalb haben wird das da wieder raus genommen. Sry für das hin und her :/
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
es gibt ein Update zum Projekt. Ich hab alles refactored und aufgeräumt. Jetzt gibt es das Projekt als komplett eigenständiges Repository. Die Links dazu findet ihr im ersten Posting. Für die nächsten Wochen ist die Umsetzung einer dynamischen Library geplant, dass das Projekt auch in anderen Sprachen genutzt werden kann. Folgende Sprachen sind bis jetzt geplant: C, C++ und Delphi. Natürlich darf sich dann auch jeder gern einen eigenen Header für die Sprache seiner Wahl schreiben, aber diese 3 Sprachen werden sozusagen out-of-the-box unterstützt.
Eine umfassende Doku wie man das ganz nun nutzt kommt natürlich auch noch. Im Vergleich zu älteren Versionen hat sich aber nicht viel geändert. Ich würde mich sehr freuen, wenn jmd ein wenig damit rum spielt und mir etwas Feedback geben könnte.
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
es ist vollbracht. Ich hab soeben v1.0.0.1 von libShaderFile gebaut. Die lib steht als Windows und Linux Binary jeweils für 32bit ud 64bit zur Verfügung. Die Links findet ihr im ersten Post. Außerdem hab ich eine umfassende Dokumentation mit simplen Code-Schnipseln geschrieben. Komplette kompilierbare Code Beispiele für C, C++, FPC/Lazarus und Delphi gibt es ebenfalls. Ich hoffe damit ist jeder versorgt. Falls es doch noch Fragen und Wünsche geben sollte, dann kann er mir gern nen Post dazu im Meinungs-Thread verfassen. Einfaches Feedback zur Nützlichkeit oder Ähnlichem sind natürlich auch gern gesehen.
Registriert: Di Apr 29, 2008 18:56 Beiträge: 1213
Programmiersprache: Delphi/FPC
Hey Leute,
hab grad ein Update (v1.0.0.3) hochgeladen. Die neue Version enthält die Möglichkeit die Shader-Files über ein Callback bzw. ein Interface zu laden. Damit ist man nicht gezwungen den ShaderCode als Datei auf der Festplatte zu lagern, sondern könnte den Code auch aus einer Datenbank, Virtuellem Dateisystem oder ähnlichem laden.
Diese Funktion war zwar im Code schon implementiert, aber noch nicht in der Bibliothek. Für diejenigen, die den Source direkt genutzt haben gibt es keine Änderungen.
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast
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.