C for graphics
aus Wikipedia, der freien Enzyklopädie
C for Graphics (Abkürzung: Cg) ist eine von NVIDIA begründete Shader-Hochsprache zum Schreiben von Vertex-Shader- und Pixel-Shader-Programmen.
Inhaltsverzeichnis |
[Bearbeiten] Hochsprache
Die Entwicklung einer Shader-Hochsprache wurde dadurch motiviert, da das Programmieren von Vertex- und Pixel-Shadern in Maschinensprache recht kompliziert und schnell unübersichtlich ist. Weitere Shader-Hochsprachen sind GLSL, HLSL und RenderMan, einen anderen Ansatz verfolgt Sh als Metasprache.
[Bearbeiten] Syntax
Cg ähnelt vom Syntax her der Programmiersprache C. Bestandteile sind u.a. einfache Datentypen, Arrays, Bedingungen und Schleifen.
[Bearbeiten] Datentypen
- int (32bit integer)
- float (32bit floating point)
- half (16bit floating point)
- fixed (12bit fixed point, 1-1-10)
- double
- bool
- sampler (für Texturobjekte)
Es sei darauf hingewiesen, dass auf manchen Grafikkarten alles auf float gerechnet wird.
Hinzu kommen die entsprechenden Vektoren und Matrizen: float2, float3, float4, float4x4.
[Bearbeiten] Parameter
Ausgabe-Parameter werden mit out gekennzeichnet:
out float4 pos : POSITION; // Eckpunkt der vom VP weitergegeben wird out float4 color : COLOR; // Farbe die vom VP weitergegeben wird
Uniform-Parameter werden außerhalb vom Vertex Program gesetzt und ändern sich nicht pro Eckpunkt:
z.B. in einem OpenGL Programm:
CGparameter timeParam = cgGetNamedParameter(vertexProgram, „time"); CGparameter modelviewParam = cgGetNamedParameter(vertexProgram, "modelview"); cgGLSetParameter1f(timeParam, 100); cgGLSetStateMatrixParameter(modelviewParam, CG_GL_MODELVIEW_MATRIX, CG_GL_MATRIX_IDENTITY);
Verwendung dann im Vertex Program:
uniform float time; uniform float4x4 modelview;
[Bearbeiten] Zugriff auf OpenGL State
Normalerweise erfolgt der Zugriff über uniform Parameter. Diese Parameter müssen im OpenGL Programm immer neu gesetzt werden. Im Falle eines ARB Profils, ist der Zugriff auf ein OpenGL State möglich, z.B.
glstate.matrix.mvp // Projection * Modelview
[Bearbeiten] Profile
Ein weiterer Aspekt ist die Möglichkeit zum kompilieren für verschiedene Profile. Das sind verschiedene Versionen von Vertex-/ Fragment-Programmen, von denen automatisch des bestmöglichen für die vorhandenen Hardware aktiviert wird:
CGprofile vertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX); cgGLSetOptimalOptions(vertexProfile); CGprofile fragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT); cgGLSetOptimalOptions(fragmentProfile);
Profil ausgeben lassen:
cgGetProfileString(fragmentProfile)
[Bearbeiten] Einbindung und Programmierung
Die erstellten Programm-Codes können separat kompiliert und als externe Quelle in ein lauffähiges Hochsprachen-Programm (z.B. C++) eingebunden werden, oder alternativ erst zur Laufzeit übersetzt werden.
Es muss zunächst ein Kontext erzeuget werden (Speicher für Programme) und das Programm kompiliert werden.
CGcontext context = cgCreateContext(); CGprogram program = cgCreateProgramFromFile(context, CG_SOURCE, filename, profile, "main", NULL); cgGLLoadProgram(program); // Programm laden
Das Programm muss aktiviert und ausgewählt werden:
// Profil aktivieren (und Programm aktivieren) cgGLEnableProfile(CGProfile profile); … // Ab hier läuft jeder glVertex() durchs eigene Vertex Program … // Profil (und Programm deaktivieren) cgGLDisableProfile(CGProfile profile) … // Ab jetzt läuft wieder jeder glVertex() durch die Standard OpenGL // Pipeline … // Aktuelles Vertex/Fragment Program festlegen cgGLBindProgram(myVertexProgram);