SelfDXD von Martin Pyka
SelfDXD --- DirectXGraphic --- Texturen
Texturen laden und anwenden
Einleitung
D3DXCreateTextureFromFile( )
D3DXCreateTextureFromFileEx( )
D3DXCreateTexture( )
Änderungen im Vertexformat
Textur anwenden
Textureinstellugen

Einleitung

Eine Textur ist in DirectXGraphics ein Interface vom Typ IDirect3DTexture8. Für das Erstellen einer Instanz dieses Interfaces gibt es mehrere Funktionen. Unter anderem haben Sie die Möglichkeit direkt mit einer Bilddatei eine Textur zu erstellen oder eine leere Textur zu erzeugen. Dieses Kapitel stellt Ihnen die wichtigsten Funktionen vor.

Zum Schluss wird gezeigt, wie welche Änderungen Sie im Vertexformat vornehmen müssen,und wie Sie die Textur grundsätzlich auf 3D-Objekte anwenden. Die verschiedenen Blending- und Filtertechniken werden in den nachfolgenden Kapiteln genauer beschrieben.


D3DXCreateTextureFromFile( )

Die wohl einfachste und gängigste Funktion. Mit dieser Funktion erstellen Sie eine Standardtextur, die in ihrer Grösse und ihrem Format abhängig von der zu ladenden Bilddatei ist. Die Syntax dieser Funktion sieht wie folgt aus:


function D3DXCreateTextureFromFile( const Device  : IDirect3DDevice8;
                                    const pSrcFile : PChar;
                                    out   ppTexture : IDirect3DTexture8 );

Device: Das Device, dem die Textur zugewiesen werden soll.

pSrcFile: Der Pfad und der Name der Bilddatei, die Sie laden möchten.

ppTexture: Eine Variable des Typs IDirect3DTexture8, die auf die erstellte Textur zeigt.

Diese Funktion ist zwar sehr einfach zu verwenden hat aber folgende Nachteile. Die Grösse der Textur entspricht immer der Grösse der Bilddatei, Sie können keine transparenten Farben verwenden und keine Mipmaps. Daher eignet sich diese Funktion nur für einfachere Zwecke. Wollen Sie eine Performanceoptimierte Textur erzeugen, mit der Sie mehr Features nutzen können, dann sollten Sie lieber den nachfolgenden fortgeschrittenen Befehl verwenden.


D3DXCreateTextureFromFileEx( )

Dies ist sozusagen die Expertenfunktion, wenn es um das Erstellen einer Textur aus einer Bilddatei heraus geht. Ihnen stehen weit aus mehr Parameter zur Verfügung, um das Texturinterface Ihren Wünschen anpassen zu können.


function D3DXCreateTextureFromFileEx( const Device    : IDirect3DDevice8;
                                      const pSrcFile  : PChar;
                                      const Width     : Cardinal;
                                      const Height    : Cardinal;
                                      const MipLevels : Cardinal;
                                      const Usage     : Cardinal;
                                      const Format    : Cardinal;
                                      const Pool      : Cardinal;
                                      const Filter    : Cardinal;
                                      const MipFilter : Cardinal;
                                      const ColorKey  : TD3DColor;
                                      const pSrcInfo  : PD3DXImageInfo;
                                      const pPalette  : pPaletteEntry;
                                      out   ppTexture : Idirect3DTexture8);

Device: Das Device, dem die Textur zugewiesen werden soll.

pSrcFile: Der Pfad und der Name der Bilddatei, die Sie laden möchten.

Width: Breite der Textur in Pixel. Wenn dieser Parameter 0 oder D3DX_DEFAULT (&FFFFFFFF) ist, wird die Breite der Bilddatei übernommen.

Height: Höhe der Textur in Pixel. Wenn dieser Parameter 0 oder D3DX_DEFAULT ist, wird die Höhe der Bilddatei übernommen.

MipLevels: Die Anzahl der Mipmaps, die benötigt wird. Wenn dieser Paramter 0 oder D3DX_DEFAULT ist, wird die Textur nur in der angegebenen Auflösung erstellt.

Usage: 0 oder D3DUSAGE_RENDERTARGET aus den D3DUSAGEFLAGS. Wenn Sie letzteres angeben, kann eine Szene auch in eine Textur gerendert werden. Dies lässt sich zum Beispiel für Spiegeleffekte nutzen. Über diese Technik erfahren Sie mehr im Kapitel Textur bearbeiten.

Format: Eine Konstante der D3DFORMAT-Aufzählungen, die das Pixelformat der Textur beschreiben. Geben sie D3DFMT_UNKNOWN an, wird das Format der Bilddatei übernommen.

Pool: Eine Konstante aus der D3DPOOL, mit der Sie bestimmen, in welchem Speicherbereich die Textur plaziert wird.

Filter: Eine oder mehrere Flags aus der D3DX_FILTER-Aufzaehlung, mit der Sie bestimmen, welche Filter Sie zum Auslesen der Textur verwenden möchten. Mit Filter können Sie einstellen, auf welche Weise der zu setzende Texturpixel aus der Bilddatei errechnet werden soll. Dadurch lässt sich die Bildqualität hinsichtlich Schärfe und Detail regeln.

MipFilter: Eine oder mehrere Flags aus der D3DX_FILTER-Aufzählung, mit der Sie bestimmen, welche Filter Sie zur Anzeige der Textur verwenden möchten. Mit Filter können Sie einstellen, auf welche Weise der zu setzende Pixel aus den Texturpixeln errechnet werden soll. Dadurch lässt sich die Bildqualität hinsichtlich Schärfe und Detail regeln.

ColorKey: Ein 32-Bit-Farbwert (egal, welche Format die Bilddatei hat), der angibt, welche Farbe als transparentes Schwarz ausgegeben werden soll. 0 deaktiviert die Schlüsselfarbe. Der Alpha-Wert gibt dabei an, wie transparent die Schlüsselfarbe sein soll. FF ist dabei vollkommen nicht-transparent. Für nichttransparentes Schwarz geben Sie also an &FF000000

pSrcInfo: Ein Zeiger auf ein Record des Typs D3DXIMAGEINFO, das mit Informationen über das Bild gefüllt wird, oder nil, wenn Sie ein solches Record nicht brauchen.

pPalette: Ein Zeiger auf ein Record des Typs TPALETTEENTRY, mit dem Sie die Farbanteile der Textur auslesen können, oder nil, wenn Sie ein solches Record nicht brauchen.

ppTexture: Ein Zeiger auf die Textur, die mit dieser Funktion erstellt wird.

In der Praxis könnte diese Funktion zum Beispiel so aussehen:

var
  textur: IDirect3DTextur8;
begin
  D3DXCreateTextureFromFileEx( d3ddev8, 'bild.bmp', 300, 300,
                               0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
                               D3DX_FILTER_LINEAR, D3DX_FILTER_NONE, $FF000000,
                               nil, nil, textur );

Hierbei wird eine Textur geladen, die 300x300 Texel gross ist. Für den Fall, dass das Bild kleiner ist als 300x300, wird durch das Lineare Filtering sichergestellt, dass man nicht jeden einzelnen Pixel des Bildes sieht, sondern jeder Texel eine individuelle Farbe besitzt, die von seiner Position abhängt.


D3DXCreateTexture( )

Mit dieser Funktion legen Sie eine leere Textur an. Diese Funktion ist praktisch, wenn Sie zur Laufzeit eine eigene Textur erzeugen wollen und dabei auf Bildinhalte aus Dateien verzichten können.


function D3DXCreateTexture( const Device    : IDirect3DDevice8;
                            const Width     : Cardinal;
                            const Height    : Cardinal;
                            const MipLevels : Cardinal;
                            const Usage     : Cardinal;
                            const Format    : Cardinal;
                            const Pool      : Cardinal;
                            out   ppTexture : Idirect3DTexture8);

Device: Das Device, dem die Textur zugewiesen werden soll.

Width: Breite der Textur in Pixel. Wenn dieser Parameter 0 oder D3DX_DEFAULT (&FFFFFFFF) ist, wird die Breite der Bilddatei übernommen.

Height: Höhe der Textur in Pixel. Wenn dieser Parameter 0 oder D3DX_DEFAULT ist, wird die Höhe der Bilddatei übernommen.

MipLevels: Die Anzahl der Mipmaps, die benötigt wird. Wenn dieser Paramter 0 oder D3DX_DEFAULT ist, wird eine komplette Mipmap-Kette erstellt.

Usage: 0 oder D3DUSAGE_RENDERTARGET aus den D3DUSAGEFLAGS. Wenn Sie letzteres angeben, kann eine Szene auch in eine Textur gerendert werden. Dies lässt sich zum Beispiel für Spiegeleffekte nutzen. Über diese Technik erfahren Sie mehr im Kapitel Textur bearbeiten genaueres.

Format: Eine Konstante der D3DFORMAT-Aufzählungen, die das Pixelformat der Textur beschreiben. Geben sie D3DFMT_UNKNOWN an, wird das Format der Bilddatei übernommen.

Pool: Eine Konstante aus der D3DPOOL, mit der Sie bestimmen, in welchem Speicherbereich die Textur plaziert wird.

ppTexture: Ein Zeiger auf die Textur, die mit dieser Funktion erstellt wird.

In der Praxis könnte diese Funktion zum Beispiel so aussehen:


var
  textur : IDirect3DTexture8;
begin
  D3DXCreateTexture( d3ddev8,
                     256, 256, 0,
                     D3DUSAGE_RENDERTARGET,
                     D3DFMT_R5G6B5,
                     D3DPOOL_DEFAULT,
                     textur );

In diesem Fall wird also eine Textur mit den Grössen 256x256 erstellt. Sie wird uns in dem Kapitel Textur bearbeiten als Rendertarget dienen.


Änderungen im Vertexformat

Bevor wir Texturen überhaupt verwenden können, müssen wir natürlich ein entsprechendes Vertexformat definieren, in dem wir Texturkoordinaten verwenden können. Da wir uns zunächst erstmal nur mit der einfachen Darstellung von Texturen beschäftigen, verwenden wir fürs erste nur ein Texturkoordinatenset.

type

  CUSTOMVERTEX = record
    x, y, z : single;
    nx, ny, nz: single;
    color: TD3DColor;
    tu, tv : Single;     // Die Texturkoordinaten 
  end;

const
  D3DFVF_CUSTOMVERTEX = ( D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF_DIFFUSE or D3DFVF_TEX1);

Statt D3DFVF_TEX1 hätten wir auch D3DFVF_TEX2 oder D3DFVF_TEX8 angeben können. Diese Flags stehen in keiner Reihenfolge. Sie geben lediglich an, dass ein Texturenset verwendet werden soll. Lediglich die Anzahl dieser Flags bestimmt also, wieviele Texturkoordinatensets Sie verwenden, nicht aber welche der Flags Sie nun angeben. Angenommen, Sie wollen zwei Texturkoordinatensets verwenden, dann könnten Sie auch angeben D3DFVF_TEX3 und D3DFVF_TEX6.

Wenn Sie nun also Ihr 3D-Objekt erstellen, müssen Sie darauf achten, dass Sie nun auch die Texturkoordinaten angeben.


Textur anwenden

Das eigentliche Anwenden einer Textur ist sehr einfach. Setzen Sie die folgende Funktion des Direct3DDevices einfach vor dem Rendern des 3D-Objektes ein:


function SetTexture(const Stage : LongWord;
                          pTexture : IDirect3DBaseTexture8) : HResult;

Stage: Indexzahl, die für die gewählte Textur verwendet wird. Da Sie ja mehrere Texturen auf ein Objekt anwenden können (zum Beispiel beim Texture Blending) wird über den Stage-Parameter jede Textur indiziert. Da Sie bis zu 8 Texturen verwenden können, sind Zahlen von 0 bis 7 erlaubt.

pTexture: Dieser Parameter kann auch vom Typ IDirect3DTexture8 sein. IDirect3DBaseTexture8 ist nur ein erweitertes Interface, dass die Verwendung von Cube oder Volumentexturen erlaubt. Möchten Sie unter einem bestimmten Stage keine Textur verwenden, genügt die Angabe von NIL.


Textureinstellungen

Alle Einstellungen, die eine Textur betreffen, werden mit einer einzigen Funktion ausgefuehrt. Die Parameter bestimmten, was Sie genau einstellen wollen, und wie Sie es einstellen wollen. Durch mehrmaliges Aufrufen dieser Funktion können Sie die Darstellung der Texturen in vielerlei Hinsicht verändern. Die Funktion des Devices lautet wie folgt.


function SetTextureStageState(const Stage : LongWord;
                              const _Type : TD3DTextureStageStateType;
                              const Value : LongWord) : HResult;

Stage: Indexzahl, der Textur, an deren Darstellung Sie etwas einstellen wollen.

_Type: Eine Konstante aus der D3DTextureStageStateType-Aufzählung, mit der Sie angeben, was genau Sie mit Value einstellen wollen.

Value: Die Eingabe dieses Wertes hängt logischerweise davon ab, was Sie genau einstellen wollen, also was Sie als _Type angegeben haben. Mehr Informationen dazu finden Sie in den D3DTextureStageStateType-Aufzählungen.

Da es schwer ist, allein durch die Definition der Konstanten zu verstehen, wie Sie eingesetzt werden, und welchen Effekt Sie haben, finden Sie in den nächsten Kapiteln genauere Erläuterungen zu den speziellen Techniken der Texturierung.