1. Vorwort
2. Einführung
3. Vertexaufbau
4. Die Wellen
5. Die Kiste
6. Das fertige Projekt
7. Fazit
8. Nachwort
Vorwort
Dieses Tutorial beschäftigt sich mit der Erstellung einer möglichst realistisch wirkenden Wasseroberfläche und baut auf der DirectX Tutorialserie von DIrectX Tutorials | Jack Hoxley auf. Da ich in VB nur sehr wenige wirklich gute Beispielcodes fand, habe ich mich entschlossen dieses Thema zu behandeln. Unser Ziel ist es diese Wasseroberfläche so flexibel, realistisch und schnell wie möglich zu machen. Hierfür verwende ich einige Rechentechniken aus der Trigonometrie, welche aber auch für jüngere Leser leicht zu verstehen sein werden. Da ich selbst noch vieles in DirectX lernen kann, würde ich mich freuen, wenn ich reichlich Emails bekommen würde um diese Szene noch realistischer wirken zu lassen. Beispielsweise könnte man diese Szenen noch mit zusätzlichem Lightning und Fogging ausstatten. Auch ist zu sagen, dass selbst Spiele wie Counterstrike nicht mit allzu realistischen Wasseroberflächen dienen können.
Einführung
Um eine Wasseroberfläche in DirectX zu erstellen, braucht man zuerst mal einen Ansatz, wie die Wellen, welche erstellt werden, auszusehen haben. Es gibt im wesentlichen 3 Arten, welche ich am sinnvollsten ansehe. Die erste Art, ist die Wellenbewegung in Form eines sich von einem Zentrum wegbewegenden Wellenzirkels. Hierzu 2 Skizzen:
Die Pfeile auf der rechten Seite stellen die Orientierung der Wellen, die Kreise die Wellen selbst dar. Die zweite Art ist eine Oberfläche, welche aus verschiedenen sich auf und ab bewegenden Aufstiegspunkten besteht. Diese Sorte lasse ich allerdings nur sehr wenig Aufmerksamkeit zukommen, da sie nicht sehr realistisch wirkt. Diese Art wurde in ersten 3D- Anwendungen verwendet.
Die hier als letzte angesprochne Wasseroberfläche ist linear, das heißt sie bewegt sich von rechts nach links, bzw. anders herum. In diesem Beispiel ist ebenfalls eine Mathematische Rechenart von Nöten. Diese Wellenbewegung wollen wir nun vertiefen. Hierzu eine Skizze:
Bevor wir aber starten, möchte ich auf die Geschwindigkeit, der oben angesprochenen Wellenarten, zu sprechen kommen. Die erste und zweite Art benötigt n² mal so viele Vertices um die Wasseroberfläche zu erstellen wie die, welche wir im Anschluss besprechen. Die erste Art benötigt von der Bearbeitung dann noch eine Pufferstärke, welche die Lineare Methode um längen übersteigt. Alles in allem, bin ich zu dem Schluss gekommen, dass die Lineare Methode für uns die beste Mischung aus Realismus, Geschwindigkeit und Flexibilität darstellt.
Vertexaufbau
Zu erst müssen wir uns um den Vertexaufbau kümmern. Hier werden Frage geklärt was für Vertices wir benötigen, welche Vor- und Nachteile sie besitzen und wie wir sie in ein „vernünftiges“ Programm bringen. Um die Flexibilität zu gewährleisten erstellen wir eine Schnittstelle von diesem Typ:
Code:
Public Sub CreateWaves(Move As Single, Wellenhöhe As Single, Fliesgeschwindigkeit As Single, Länge As Single, Breite As Single) […] End Sub
Es gibt verschiede Möglichkeiten und Vertexarten um die Wasseroberfläche zu gestallten. Ich denke, dass es einleuchtet, wenn wir zur Erstellung Dreieck-Strips (D3DPT_TRIANGLESTRIP) verwenden. Ich habe das gleiche Beispiel einmal mit Dreieck-Listen (D3DPT_TRIANGLELIST) programmiert. Allerdings sind hier unschöne Lücken aufgetreten. Wahrscheinlich waren es Rundungsfehler. Mit den Dreieck- Strips tritt so etwas natürlich nicht auf. Außerdem ist die Arbeit mit der Textur anschließend wesentlich leichter. In diesem Bild kann man schon einige Ansätze an Wellen erkennen. Wir benötigen in der fertigen Wasseroberfläche 60 Aufzugspunkte. Natürlich ist es anschließend dem Leser vorbehalten diese Zahl zu ändern. Mehr machen die Oberfläche genauer aber auch langsamer.
Nun zu der Architektur der Oberfläche, die y- Koordinate der Vertices besprechen wir direkt im Anschluss, denn noch sind sie nicht wichtig für uns.
Um dieses Netz zu kreieren brauchen wir eine Schleife, die jeweils den geraden und ungeraden Vertex bearbeitet.
Code:
For X = -15 To 15 […] Next X Die Schleife bearbeitet insgesamt (15 - (-15)) * 2 = 60 Punkte Hier die Vertices. Zunächst beschreibe ich die Parameter, welche für uns von Interesse sind. Dim Waves(61) As LITVERTEX Waves((X + 15) * 2 + 0) = CreateLitVertex(X * Länge, Sin(X + move) * Wellenhöhe _ , Breite, C110, 0, ((X + 15) / 30) + move / Fliesgeschwindigkeit, 1) Waves((X + 15) * 2 + 1) = CreateLitVertex(X * Länge, Sin(X + move) * Wellenhöhe _ , -Breite, C010, 0, ((X + 15) / 30) + move / Fliesgeschwindigkeit, 0)
Der erste Parameter stellt die X- Koordinate dar. „Länge“ ist dafür verantwortlich die Wasseroberfläche zu strecken. Der dritte Parameter stellt lediglich die Breite der Wasseroberfläche dar. Ich habe die Breite 30 gewählt. Nummer 4 ist die Farbe des einzelnen Vertex, hier eine Konstante, welche ist aus den vorhergegangenen Tutorials von Jack Hoaxley übernommen habe. Parameter Nummer 5 hat für uns ebenfalls keine Bedeutung. Die letzten beiden Parameter sind für die Textur verantwortlich.
Code:
Dim Texture As Direct3DTexture8 Set Texture = D3DX.CreateTextureFromFileEx(D3DDevice, App.Path & "\wasser.jpg", 128, 128, D3DX_DEFAULT, 0, DispMode.Format, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR, 0, ByVal 0, ByVal 0)






