In diesem Tutorial werden Grafiken als texturierte Graph::PlaneGeometry
-Objekte gezeichnet. Dabei ist zu beachten, dass die Breite und Höhe der Textur eine Zahl aus der Reihe 2^n sein muss (Power of 2). Gültige Werte sind z.B. 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 etc.
Version 1: 2D-Textur
Für unser Beispiel erzeugen wir eine Grafik mit dem Namen gfx_smiley.png
und speichern diese im Unterordner gfx
ab. Die Grafik wird in der Datei package.xml
bekannt gemacht:
<Resource id="gfx_smiley" fileName="gfx/gfx_smiley.png"/>
Für das Zeichnen der Grafik benötigen wir ein geignetes Material, bei dem die erste Textur-Einheit (Unit 0) aktiviert ist. Dieses Material erstellen wir in der Datei graph_materials.xml
. Mit textureUnit0Enabled
wird die Textur-Einheit 0 aktiviert und die Angabe von blendMode="ALPHA"
erlaubt transparente Bereiche beim Zeichnen der Grafik.
<?xml version="1.0"?> <Graph> <Namespace id="material" activeAndVisible="no"> <FixedProgram id="prg_color_texture" textureUnit0Enabled="yes" /> <Material id="mat_alpha_color_texture" programId="prg_color_texture" visibleFaces="FRONT_AND_BACK" blendMode="ALPHA" depthBufferMode="NONE" />
Zusätzlich erzeugen wir einen Graph::FlatTexture
-Knoten, der die Grafikressource als Graphenknoten instanziert. Das Attribut pixelFormat
definiert das Format der Grafik im Speicher. Das Pixelformat der Grafikdatei kann dabei durchaus ein anderes sein.
Mit dem Attribut useMipMaps
kann die automatische Mip-Map-Generierung aktiviert werden. Dabei wird beim Laden der Grafik eine Mip-Map-Bildpyramide erzeugt. Ein Aktivieren hat daher höhere Ladezeiten und einen um 50% höheren Speicherbedarf zur Folge. Für 2D Anwendungen wird Mip-Mapping normalerweise eher selten benötigt, weshalb wir es auch für dieses Beispiel deaktivieren.
<FlatTexture id="texture_smiley" imageResourceId="package_main:gfx_smiley" pixelFormat="R8_G8_B8_A8" useMipMaps="no" /> </Namespace> </Graph>
In der Datei graph_main.xml
erzeugen wir eine Instanz dieser Objekte und aktivieren Sie für die folgenden Zeichenoperationen mit MaterialState
bzw. TextureState
.
<?xml version="1.0" ?> <Graph> <Instance graphResourceId="package_main:graph_mat"/> <Instance graphResourceId="package_main:graph_camera"/> <MaterialState materialId="material/mat_alpha_color_texture"/> <TextureState textureId="material/texture_smiley"/> <PlaneGeometry id="plane" scaleFactorX="128" scaleFactorY="128" /> </Graph>
Als Ergebnis erhalten wir ein texturiertes PlaneGeometry
-Objekt:
Version 2: Position und Größenänderung
Die Textur wird immer in das Objekt eingepasst. Je nach Größe und Seitenverhältnis des Objekts, wird die Textur entsprechend skaliert und/oder verzerrt (siehe Screenshot unten).
Mit den Attributen texCoordX1
, texCoordX2
, texCoordY1
und texCoordY2
kann ein Ausschnitt aus der Textur ausgewählt werden (Screenshot unten).
<PlaneGeometry id="plane7" scaleFactorX="64" scaleFactorY="128" texCoordX1="0.0" texCoordX2="0.5" texCoordY1="0.0" texCoordY2="1.0" posX="150" posY="0" /> <PlaneGeometry id="plane8" scaleFactorX="128" scaleFactorY="64" texCoordX1="0.0" texCoordX2="1.0" texCoordY1="0.0" texCoordY2="0.5" posX="-150" posY="0" />
Wenn durch die Position des Geometrieobjekts die einzelnen Pixel der Texturgrafik genau zwischen die Pixel der Display-Surface zu liegen kommen, erscheint das Bild durch die Interpolation unscharf (siehe unterste Reihe im Bild oben).
Um diese Unschärfe zu verhindern, müssen Grafiken mit einer geradzahligen Pixellänge auf einer ganzzahligen Position platziert werden. Grafiken mit ungeradzahliger Länge müssen genau zwischen zwei ganzzahligen Positionen platziert werden.
Version 3: Farbige Textur
Wenn coloringEnabled
und textureUnit0Enabled
eingeschaltet sind, ergibt sich die Zeichenfarbe durch Multiplikation der beiden Farbparameter. Das kann zum Beispiel für Fade-In/Fade-Out Effekte (Alphakanal) oder zum Einfärben von Texturen verwendet werden.
<FixedProgram id="prg_color_texture" textureUnit0Enabled="yes" coloringEnabled="yes" />
Zur besseren Veranschaulichung erstellen wir verschiedene Materialknoten und zeichnen damit jeweils zwei überlappende PlaneGeometry
-Objekte. Die Parameter für Kamera, Licht, Textur und Farbe sind für alle Objekte gleich. Die Reihung erfolgt analog dem Lesefluss von links nach rechts und von oben nach unten.
<FixedProgram id="prg_white" /> <Material id="mat_white" programId="prg_white" /> <FixedProgram id="prg_color" coloringEnabled="yes" /> <Material id="mat_color" programId="prg_color" />
Die ersten beiden Objekte werden mit den Materialen mat_white
und mat_color
gezeichnet. Obwohl ein Texturparameter gesetzt ist, wird dieser nicht gezeichnet, da textureUnit0Enabled
nicht aktiviert wurde.
<FixedProgram id="prg_texture" textureUnit0Enabled="yes" /> <Material id="mat_texture" programId="prg_texture" visibleFaces="FRONT_AND_BACK" blendMode="NONE" depthBufferMode="NONE" /> <Material id="mat_alpha_texture" programId="prg_texture" visibleFaces="FRONT_AND_BACK" blendMode="ALPHA" depthBufferMode="NONE" /> <FixedProgram id="prg_color_texture" textureUnit0Enabled="yes" coloringEnabled="yes" /> <Material id="mat_color_texture" programId="prg_color_texture" visibleFaces="FRONT_AND_BACK" blendMode="NONE" depthBufferMode="NONE" /> <Material id="mat_alpha_color_texture" programId="prg_color_texture" visibleFaces="FRONT_AND_BACK" blendMode="ALPHA" depthBufferMode="NONE" />
Bei den nächsten vier Objekten wurde die Textur-Einheit 0 aktiviert. Die Materialien unterscheiden sich durch unterschiedliche Werte für die Attribute coloringEnabled
und blendMode
. Nur wenn der blendMode
auf "ALHA"
gesetzt ist, wird der Alphakanal (Transparenz) beim Zeichnen berücksichtigt. Der Farbparameter hat einen Alpha-Wert von 0.5, weshalb das vierte Objekt halbdurchsichtig gezeichnet wird.
<FixedProgram id="prg_texture_light" textureUnit0Enabled="yes" coloringEnabled="no" lightingEnabled="yes" /> <Material id="mat_texture_light" programId="prg_texture_light" visibleFaces="FRONT_AND_BACK" blendMode="ALPHA" depthBufferMode="NONE" /> <FixedProgram id="prg_color_texture_light" textureUnit0Enabled="yes" coloringEnabled="yes" lightingEnabled="yes" /> <Material id="mat_color_light" programId="prg_color_texture_light" visibleFaces="FRONT_AND_BACK" blendMode="NONE" depthBufferMode="NONE" /> <Material id="mat_alpha_color_texture_light" programId="prg_color_texture_light" visibleFaces="FRONT_AND_BACK" blendMode="ALPHA" depthBufferMode="NONE" />
Bei den letzten drei Objekten wurde zusätzlich das Attribut lightingEnabled
auf "yes"
gesetzt. Dadurch ergibt sich mit der passenden Lichtquelle ein einfacher Beleuchtungseffekt.
- Zu beachten
- Achtung: Für eine korrekte Beleuchtungsberechnung muss bei den entsprechenden
PlaneGeometry
-Objekten auch das AttributhasNormal
auf"yes"
gesetzt werden. Das setzten des Attributs bewirkt, dass für diese Geometrie-Objekte auch die für die Beleuchtungsberechnung notwendigen Normalvektoren berechnet werden.
<MaterialState materialId="material/mat_texture_light"/> <PlaneGeometry id="plane6" hasNormal="yes" scaleFactorX="128" scaleFactorY="128" posX="-150" posY="-150" /> <PlaneGeometry id="plane6a" hasNormal="yes" scaleFactorX="128" scaleFactorY="128" posX="-145" posY="-145" depthOrder="1" />