\chapter{Shader}

    Nachdem der Boxcode zum Laden und Binden von Shadern nun fertig ist koennen wir endlich
    unsere eigenen Shader schreiben und ausfuehren:

    \section{Monocolor Shader}
    Der wohl einfachste Shader ist der welcher die Vertices unveraendert laesst und einfach 
    alle Fragmente auf eine bestimmte Farbe setzt.

    Der komplette Source dieses Shaders ist in den Dateien im Verzeichnis \emph{shader/monocolor}
    zu finden. Ausgefuehrt wird er mittels 

    ./gltut shader/monocol/monocol.avp shader/monocol/monocol.afp
    respektive

    ./gltut shader/monocol/monocol.avs shader/monocol/monocol.afs

        \subsection{ARB Program Monocolor Shader}
        Zunaechst soll die Umsetzung dieses Vorhabens mittels der ARB Programs Extensions
        gezeigt werden:

        \begin{lstlisting}[name=monocolor.avp]
!!ARBvp1.0
PARAM mvp[4] = { state.matrix.mvp };

DP4 result.position.x, mvp[0], vertex.position;
DP4 result.position.y, mvp[1], vertex.position;
DP4 result.position.z, mvp[2], vertex.position;
DP4 result.position.w, mvp[3], vertex.position;

END
        \end{lstlisting}
        ARB Vertex Programs werden immer mit \emph{!!ARBvp} gefolgt von einer Versionsnummer
        eingeleitet. Danach wird
        hier eine Variable namens \emph{mvp} bekannt gemacht welche vom Typ \emph{PARAM}
        ist und somit eine Variable die von OpenGL vorbelegt wird. Variablen sind immer
        Vierkomponenten-Vektoren bestehend aus Floats. In diesem Fall handelt es sich um
        ein Array von vier dieser Vektoren die mit den Komponenten der ModelviewProjection-Matrix 
        - dem Ergebnis der Multiplikation der Modelview- mit der Projektions-Matrix - 
        vorbelegt werden.

        Mit dem Befehl \emph{DP4} wird ein Punktprodukt von zwei Vierkomponenten-Vektoren
        erzeugt und im ersten Operanden gespeichert.

        Die Variable \emph{vertex} enthaelt den Vertex auf dem der Shader gerade ausgefuehrt 
        wird, die Variable \emph{result} ist der Ergebnisvertex.

        In diesem Shader wird die Position des Vertex einfach mit der ModelviewProjection-Matrix 
        (ab jetzt kurz MVP genannt) multipliziert und in result gespeichert.

        Das zugehoerige Fragment Program gestaltet sich folgendermassen:

        \begin{lstlisting}[name=monocolor.afp]
!!ARBfp1.0
PARAM c[1] = { { 0, 1 } };
MOV result.color, c[0].xxyy;
END
        \end{lstlisting}

        ARB Fragment Programs werden immer mit \emph{!!ARBfp} eingeleitet, auch hier gefolgt
        von einer Versionsnummer. Nachdem eine Variable namens \emph{c} mit konstanten Werten
        vorbelegt wurde wird die Farbe des Ergebnisfragmentes \emph{result} auf {0.0, 0.0, 1.0, 1.0}
        - also blau - gesetzt.

        \subsection{GLSL Monocolor Shader}
        Nachdem wir den Shader jetzt mittels der ARB Programs umgesetzt haben wollen wir ihn auch
        in GLSL schreiben:

        \begin{lstlisting}[name=monocolor.avs]
void main() {
    vec4 v = vec4(gl_Vertex);       

    gl_Position = gl_ModelViewProjectionMatrix * v;
}
        \end{lstlisting}
        Es ist leicht ersichtlich dass GLSL deutlich eingaengiger als der Pseudo-Assembler
        der ARB Programs ist.

        GLSL lehnt sich stark an C an, somit heisst der Einsprungspunkt auch hier \emph{main},
        ist allerdings als \emph{void} definiert. Der Vertex auf dem der Shader ausgefuehrt wird 
        heisst hier \emph{gl\_Vertex}, die Position des Ergebnisvertexes heisst \emph{gl\_Position}.

        Nun wird hier eine Variable vom Typ \emph{vec4} definiert und mit der Position von gl\_Vertex
        belegt. Die Ergebnisposition ergibt sich einfach aus der Multiplikation der MVP mit diesem
        Vektor.

        Der Source des zugehoerigen Fragment Shaders ist aehnlich einfach:
        
        \begin{lstlisting}[name=monocolor.avs]
void main() {
	vec4 color = vec4(0.0, 0.0, 1.0, 1.0);
		
	gl_FragColor = color;
}
        \end{lstlisting}
        Auch hier heisst der Einsprungspunkt main, die Ausgabefarbe des Fragmentes auf dem
        der Shader ausgefuehrt wird heisst \emph{gl\_FragColor}. Wieder wird eine Variable definiert,
        allerdings wird sie hier einfach mit konstanten Werten fuer blau belegt. Die Ergebnisfarbe
        ergibt sich einfach aus diesen Werten.

        \begin{figure}
            \centering
            \includegraphics{images/monocolor}
            \caption{Der monocolor Shader in seiner gesammten Pracht}
            \label{fig:monocolor}
        \end{figure}
        

    \section{Flat Shader}
    Wir wollen nun einen einfach Vertex Shader schreiben der einfach alle
    Z-Koordinaten der im Stream befindlichen Vertices auf 0 setzt, das
    Objekt sozusagen flach drueckt.

    \section{Flag Shader}
    -- Flagge - z = sin(x) --
    keine lighting -> spaeter

    \section{Toon Shader}

    \section{Lighting}
    -- fixed function pipeline nachbauen --

    \section{Flagge, die 2.}
    -- Flagge mit lighting --

    \section{wehende Flagge}
    -- Flagge in Bewegung (Parameter) --
    (Farbe auch?)

