summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--de-de/dhall-de.html.markdown380
-rw-r--r--dhall.html.markdown6
-rw-r--r--directx9.html.markdown827
-rw-r--r--mercury.html.markdown263
-rw-r--r--tr-tr/clojure-tr.html.markdown1
-rw-r--r--tr-tr/edn-tr.html.markdown157
6 files changed, 1631 insertions, 3 deletions
diff --git a/de-de/dhall-de.html.markdown b/de-de/dhall-de.html.markdown
new file mode 100644
index 00000000..385c88be
--- /dev/null
+++ b/de-de/dhall-de.html.markdown
@@ -0,0 +1,380 @@
+---
+language: Dhall
+contributors:
+ - ["Gabriel Gonzalez", "http://www.haskellforall.com/"]
+translators:
+ - ["Profpatsch", "http://profpatsch.de"]
+filename: learndhall-de.py
+lang: de-de
+---
+
+Dhall ist eine programmierbare Konfigurationssprache und bietet eine
+nicht-repetetive Alternative zu YAML.
+
+Man kann Dhall sehen als: JSON + Funktionen + Typen + Importsystem
+
+Obwohl Dhall programmierbar ist, ist die Sprache nicht
+turingvollständig. Viele von Dhalls Features benutzen diese
+Einschränkung, um stärkere Sicherheitsgarantien zu bieten und besseres
+Tooling zu ermöglichen.
+
+```haskell
+-- einzeiliger Kommentar
+
+{- mehrzeiliger Kommentar
+
+ Unicode funktioniert 🙂
+
+ Diese Datei ist eine valide Dhall-Expression und evaluiert zu einem
+ großen Record, welcher die Ergebnisse jedes Schritts beinhaltet.
+
+ Das Ergebnis kann angezeigt werden, indem man die Datei evaluiert:
+
+ $ dhall --file learndhall.dhall
+
+ {- Kommentare können verschachtelt sein -}
+-}
+
+let greeting = "Hallo, Welt!"
+
+let fruits = "🍋🍓🍍🍉🍌"
+
+let interpolation = "Ein paar leckere Früchte: ${fruits}"
+
+let multilineText {- Inline-Kommentare funktionieren ebenfalls -} =
+ ''
+ In Multiline-Text-Literals wird Whitespace am Anfang der Zeile
+ entfernt.
+
+ Das bedeutet Text kann frei eingerückt oder ausgerückt werden,
+ ohne dass sich der Inhalt des Strings ändert.
+
+ Relative Einrückungen bleiben erhalten.
+
+ Ansonsten wird das Text-Literal verbatim erhalten, ähnlich
+ zu “literal”-Multiline-Strings in YAML.
+ ''
+
+let bool = True
+
+-- Typannotationen für Bindings sind optional, aber hilfreich, also
+-- benutzen wir sie hier.
+let annotation : Bool = True
+
+let renderedBool : Text = if bool then "True" else "False"
+
+-- Natürliche Zahlen sind nicht-negativ und vorzeichenlos.
+let naturalNumber : Natural = 42
+
+-- Integer können negativ sein, brauchen aber ein explizites Vorzeichen.
+let positiveInteger : Integer = +1
+
+let negativeInteger : Integer = -12
+
+let pi : Double = 3.14159265359
+
+{- Identifier dürfen eine große Anzahl an verschiedenen Zeichen
+ beinhalten (wie z.B. Anführungszeichen oder Whitespace), wenn man
+ sie mit Backticks umschließt.
+-}
+let `Avogadro's Number` : Double = 6.0221409e+23
+
+let origin : { x : Double, y : Double } = { x = 0.0, y = 0.0 }
+
+let somePrimes : List Natural = [ 2, 3, 5, 7, 11 ]
+
+{- Ein Schema ist das gleiche wie ein Typ.
+
+ Typnamen beginnen konventionell mit einem Großbuchstaben, was
+ jedoch nicht erzwungen wird.
+-}
+let Profile : Type
+ = { person :
+ { name : Text
+ , age : Natural
+ }
+ , address :
+ { country : Text
+ , state : Text
+ , city : Text
+ }
+ }
+
+let bernd : Profile =
+ { person =
+ { name = "Bernd Lauert"
+ , age = 67
+ }
+ , address =
+ { country = "Deutschland"
+ , state = "Bayern"
+ , city = "Augsburg"
+ }
+ }
+
+let augsburg : Text = bernd.address.city
+
+{- Enum-Alternativen beginnen konventionell auch mit einem
+ Großbuchstaben. Das wird ebenfalls nicht erzwungen.
+-}
+let DNA : Type = < Adenine | Cytosine | Guanine | Thymine >
+
+let dnaSequence : List DNA = [ DNA.Thymine, DNA.Guanine, DNA.Guanine ]
+
+let compactDNASequence : List DNA =
+ let a = DNA.Adenine
+ let c = DNA.Cytosine
+ let g = DNA.Guanine
+ let t = DNA.Thymine
+ in [ c, t, t, a, t, c, g, g, c ]
+
+-- Enums werden transformiert, indem man einen Record mit einem Feld
+-- pro Alternative angibt.
+let theLetterG : Text =
+ merge
+ { Adenine = "A"
+ , Cytosine = "C"
+ , Guanine = "G"
+ , Thymine = "T"
+ }
+ DNA.Guanine
+
+let presentOptionalValue : Optional Natural = Some 1
+
+let absentOptionalValue : Optional Natural = None Natural
+
+let points : List { x : Double, y : Double } =
+ [ { x = 1.1, y = -4.2 }
+ , { x = 4.4, y = -3.0 }
+ , { x = 8.2, y = -5.5 }
+ ]
+
+{- `Natural -> List Natural` ist der Funktionstyp mit Eingabetyp
+ `Natural` und Ausgabetyp `List Natural`.
+
+ Alle Funktionen in Dhall sind Anonyme Funktionen (aka. „Lambdas“),
+ denen man optional einen Namen geben kann.
+
+ Die folgende Funktion beispielsweise ist äquivalent zu diesem
+ Python Code:
+
+ lambda n : [ n, n + 1 ]
+
+ ... und diesem Javascript Code:
+
+ function (n) { return [ n, n + 1 ]; }
+-}
+let exampleFunction : Natural -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+-- Dhall unterstützt auch Unicode-Syntax, aber dieses Tutorial nutzt
+-- die ASCII-Syntax.
+let unicodeFunction : Natural → List Natural =
+ λ(n : Natural) → [ n, n + 1 ]
+
+-- Funktionsargumente brauchen keine Klammern.
+let exampleFunctionApplication : List Natural =
+ exampleFunction 2
+
+let functionOfMultipleArguments : Natural -> Natural -> List Natural =
+ \(x : Natural) -> \(y : Natural) -> [ x, y ]
+
+let functionAppliedToMultipleArguments : List Natural =
+ functionOfMultipleArguments 2 3
+
+{- Wie `exampleFunction`, aber wir geben dem Eingabetypen
+ einen Namen, `n`.
+-}
+let namedArgumentType : forall (n : Natural) -> List Natural =
+ \(n : Natural) -> [ n, n + 1 ]
+
+{- Bekommt der Eingabetyp einen Namen, kann man ihn weiter hinten in
+ der gleichen Typdefinition wiederverwenden.
+
+ Das ermöglicht Funktionen, die mit mehr als einem Eingabetypen
+ arbeiten können (aka. „polymorphe“ Funktionen).
+-}
+let duplicate : forall (a : Type) -> a -> List a =
+ \(a : Type) -> \(x : a) -> [ x, x ]
+
+let duplicatedNumber : List Natural =
+ duplicate Natural 2
+
+let duplicatedBool : List Bool =
+ duplicate Bool False
+
+{- Die Sprache hat auch eine handvoll eingebauter polymorpher
+ Funktionen, wie zum Beispiel:
+
+ List/head : forall (a : Type) -> List a -> Optional a
+-}
+let firstPrime : Optional Natural = List/head Natural somePrimes
+
+let functionOfARecord : { x : Natural, y : Natural } -> List Natural =
+ \(args : { x : Natural, y : Natural }) -> [ args.x, args.y ]
+
+let functionAppliedToARecord : List Natural =
+ functionOfARecord { x = 2, y = 5 }
+
+{- Alle Typkonversionen sind explizit.
+
+ `Natural/show` ist eine eingebaute Funktion mit dem Typ:
+
+ Natural/show : Natural -> Text
+
+ ... welche `Natural`s in ihre `Text`-Repräsentation konvertiert.
+-}
+let typeConversion : Natural -> Text =
+ \(age : Natural) -> "Ich bin ${Natural/show age} Jahre alt!"
+
+-- Ein „Template“ ist einfach eine Funktion mit Ausgabetyp `Text`.
+let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
+ \(args : { year : Natural, copyrightHolder : Text }) ->
+''
+Copyright ${Natural/show args.year} ${args.copyrightHolder}
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+''
+
+-- Template-Instanziierung ist das gleiche wie Funktionsanwendung.
+let templatedLicense : Text =
+ mitLicense { year = 2019, copyrightHolder = "Jane Smith" }
+
+{- Expressions können via URL importiert werden.
+
+ Ähnlich wie in Bash kann man Code aus dem lokalen Dateisystem
+ importieren (wird nicht gezeigt).
+
+ Sicherheitsbewusste Nutzer können via URLs importierte Expressions
+ mit einem semantischen Integritätscheck versehen („pinnen“).
+ Für gepinnte Imports wird der Dhall-Interpreter jeden Versuch
+ vereiteln, auf der Remote-Seite die Expression zu manipulieren.
+ Jedoch werden Änderungen, die den Inhalt der importierten
+ Expression nicht verändern trotzdem akzeptiert.
+
+ Auf diese Weise gepinnte Expressions werden auch in einem
+ Content-Adressable Store lokal gecached (standardmäßig in
+ `~/.cache/dhall`).
+-}
+let Natural/sum : List Natural -> Natural =
+ https://prelude.dhall-lang.org/Natural/sum
+ sha256:33f7f4c3aff62e5ecf4848f964363133452d420dcde045784518fb59fa970037
+
+let twentyEight : Natural = Natural/sum somePrimes
+
+-- Ein „Paket“ ist einfach ein (möglicherweise verschachtelter)
+-- Record, den man importiert.
+let Prelude = https://prelude.dhall-lang.org/package.dhall
+
+let false : Bool = Prelude.Bool.not True
+
+-- Durch das Anhängen von `as Text` wird eine Datei verbatim
+-- importiert und nicht als Dhall-Code interpretiert.
+let sourceCode : Text = https://prelude.dhall-lang.org/Bool/not as Text
+
+-- Environment-Variablen können auch imortiert werden.
+let presentWorkingDirectory = env:PWD as Text
+
+-- Mit `?` kann man eine “Fallback-Expression” angeben, für den Fall
+-- dass ein Import fehlschlägt.
+let home : Optional Text = Some env:HOME ? None Text
+
+-- Fallback-Expressions können auch alternative Imports enthalten.
+let possiblyCustomPrelude =
+ env:DHALL_PRELUDE
+ ? https://prelude.dhall-lang.org/package.dhall
+
+{- Ein ausführliches Beispiel, welches mithilfe der
+ `generate`-Funktion eine Konfiguration für 10 Build-User generiert:
+
+ Prelude.List.generate
+ : Natural -> forall (a : Type) -> (Natural -> a) -> List a
+-}
+let buildUsers =
+ let makeUser = \(user : Text) ->
+ let home = "/home/${user}"
+ let privateKey = "${home}/.ssh/id_ed25519"
+ let publicKey = "${privateKey}.pub"
+ in { home = home
+ , privateKey = privateKey
+ , publicKey = publicKey
+ }
+
+ let buildUser =
+ \(index : Natural) -> makeUser "build${Natural/show index}"
+
+ let Config =
+ { home : Text
+ , privateKey : Text
+ , publicKey : Text
+ }
+
+ in Prelude.List.generate 10 Config buildUser
+
+-- Alle Ergebnisse in einem großen Record
+in { greeting = greeting
+ , fruits = fruits
+ , interpolation = interpolation
+ , multilineText = multilineText
+ , bool = bool
+ , annotation = annotation
+ , renderedBool = renderedBool
+ , naturalNumber = naturalNumber
+ , positiveInteger = positiveInteger
+ , negativeInteger = negativeInteger
+ , pi = pi
+ , `Avogadro's Number` = `Avogadro's Number`
+ , origin = origin
+ , somePrimes = somePrimes
+ , bernd = bernd
+ , augsburg = augsburg
+ , dnaSequence = dnaSequence
+ , compactDNASequence = compactDNASequence
+ , theLetterG = theLetterG
+ , presentOptionalValue = presentOptionalValue
+ , absentOptionalValue = absentOptionalValue
+ , points = points
+ , exampleFunction = exampleFunction
+ , unicodeFunction = unicodeFunction
+ , exampleFunctionApplication = exampleFunctionApplication
+ , functionOfMultipleArguments = functionOfMultipleArguments
+ , functionAppliedToMultipleArguments = functionAppliedToMultipleArguments
+ , namedArgumentType = namedArgumentType
+ , duplicate = duplicate
+ , duplicatedNumber = duplicatedNumber
+ , duplicatedBool = duplicatedBool
+ , firstPrime = firstPrime
+ , functionOfARecord = functionOfARecord
+ , functionAppliedToARecord = functionAppliedToARecord
+ , typeConversion = typeConversion
+ , mitLicense = mitLicense
+ , templatedLicense = templatedLicense
+ , twentyEight = twentyEight
+ , false = false
+ , sourceCode = sourceCode
+ , presentWorkingDirectory = presentWorkingDirectory
+ , home = home
+ , buildUsers = buildUsers
+ }
+```
+
+Mehr Infos und Lernmaterialien gibt es auf der offiziellen Website
+(Englisch), auf der man Dhall auf im Browser ausprobieren kann:
+
+* [https://dhall-lang.org](http://dhall-lang.org/)
diff --git a/dhall.html.markdown b/dhall.html.markdown
index 21126c8a..704a94ee 100644
--- a/dhall.html.markdown
+++ b/dhall.html.markdown
@@ -11,7 +11,7 @@ alternative to YAML.
You can think of Dhall as: JSON + functions + types + imports
Note that while Dhall is programmable, Dhall is not Turing-complete. Many
-of Dhall's features take advantage of this restriction to provider stronger
+of Dhall's features take advantage of this restriction to provide stronger
safety guarantees and more powerful tooling.
```haskell
@@ -216,7 +216,7 @@ let functionAppliedToARecord : List Natural =
let typeConversion : Natural -> Text =
\(age : Natural) -> "I am ${Natural/show age} years old!"
--- A template is the same thing as a function whose output type is `Text`
+-- A "template" is the same thing as a function whose output type is `Text`
let mitLicense : { year : Natural, copyrightHolder : Text } -> Text =
\(args : { year : Natural, copyrightHolder : Text }) ->
''
@@ -263,7 +263,7 @@ let Natural/sum : List Natural -> Natural =
let twentyEight : Natural = Natural/sum somePrimes
--- A package is the same thing as a (possibly nested) record that you can import
+-- A "package" is the same thing as a (possibly nested) record that you can import
let Prelude = https://prelude.dhall-lang.org/package.dhall
let false : Bool = Prelude.Bool.not True
diff --git a/directx9.html.markdown b/directx9.html.markdown
new file mode 100644
index 00000000..b51f418d
--- /dev/null
+++ b/directx9.html.markdown
@@ -0,0 +1,827 @@
+---
+category: tool
+tool: DirectX 9
+filename: learndirectx9.cpp
+contributors:
+ - ["Simon Deitermann", "s.f.deitermann@t-online.de"]
+---
+
+**Microsoft DirectX** is a collection of application programming interfaces (APIs) for handling tasks related to
+multimedia, especially game programming and video, on Microsoft platforms. Originally, the names of these APIs
+all began with Direct, such as Direct3D, DirectDraw, DirectMusic, DirectPlay, DirectSound, and so forth. [...]
+Direct3D (the 3D graphics API within DirectX) is widely used in the development of video games for Microsoft
+Windows and the Xbox line of consoles.<sup>[1]</sup>
+
+In this tutorial we will be focusing on DirectX 9, which is not as low-level as it's sucessors, which are aimed at programmers very familiar with how graphics hardware works. It makes a great starting point for learning Direct3D. In this tutorial I will be using the Win32-API for window handling and the DirectX 2010 SDK.
+
+## Window creation
+
+```cpp
+#include <Windows.h>
+
+bool _running{ false };
+
+LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ // Handle incoming message.
+ switch (msg) {
+ // Set running to false if the user tries to close the window.
+ case WM_DESTROY:
+ _running = false;
+ PostQuitMessage(0);
+ break;
+ }
+ // Return the handled event.
+ return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine, int nCmdShow) {
+ // Set window properties we want to use.
+ WNDCLASSEX wndEx{ };
+ wndEx.cbSize = sizeof(WNDCLASSEX); // structure size
+ wndEx.style = CS_VREDRAW | CS_HREDRAW; // class styles
+ wndEx.lpfnWndProc = WndProc; // window procedure
+ wndEx.cbClsExtra = 0; // extra memory (struct)
+ wndEx.cbWndExtra = 0; // extra memory (window)
+ wndEx.hInstance = hInstance; // module instance
+ wndEx.hIcon = LoadIcon(nullptr, IDI_APPLICATION); // icon
+ wndEx.hCursor = LoadCursor(nullptr, IDC_ARROW); // cursor
+ wndEx.hbrBackground = (HBRUSH) COLOR_WINDOW; // background color
+ wndEx.lpszMenuName = nullptr; // menu name
+ wndEx.lpszClassName = "DirectXClass"; // register class name
+ wndEx.hIconSm = nullptr; // small icon (taskbar)
+ // Register created class for window creation.
+ RegisterClassEx(&wndEx);
+ // Create a new window handle.
+ HWND hWnd{ nullptr };
+ // Create a new window handle using the registered class.
+ hWnd = CreateWindow("DirectXClass", // registered class
+ "directx window", // window title
+ WS_OVERLAPPEDWINDOW, // window style
+ 50, 50, // x, y (position)
+ 1024, 768, // width, height (size)
+ nullptr, // parent window
+ nullptr, // menu
+ hInstance, // module instance
+ nullptr); // struct for infos
+ // Check if a window handle has been created.
+ if (!hWnd)
+ return -1;
+ // Show and update the new window.
+ ShowWindow(hWnd, nCmdShow);
+ UpdateWindow(hWnd);
+ // Start the game loop and send incoming messages to the window procedure.
+ _running = true;
+ MSG msg{ };
+ while (_running) {
+ while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+ return 0;
+}
+```
+
+This should create a window, that can the moved, resized and closed.
+
+## Direct3D initialization
+
+```cpp
+// Includes DirectX 9 structures and functions.
+// Remember to link "d3d9.lib" and "d3dx9.lib".
+// For "d3dx9.lib" the DirectX SDK (June 2010) is needed.
+// Don't forget to set your subsystem to Windows.
+#include <d3d9.h>
+#include <d3dx9.h>
+// Includes the ComPtr, a smart pointer automatically releasing COM objects.
+#include <wrl.h>
+using namespace Microsoft::WRL;
+// Next we define some Direct3D9 interface structs we need.
+ComPtr<IDirect3D9> _d3d{ };
+ComPtr<IDirect3DDevice9> _device{ };
+```
+
+With all interfaces declared we can now initialize Direct3D.
+
+```cpp
+bool InitD3D(HWND hWnd) {
+ // Store the size of the window rectangle.
+ RECT clientRect{ };
+ GetClientRect(hWnd, &clientRect);
+ // Initialize Direct3D
+ _d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ // Get the display mode which format will be the window format.
+ D3DDISPLAYMODE displayMode{ };
+ _d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, // use default graphics card
+ &displayMode); // display mode pointer
+ // Next we have to set some presentation parameters.
+ D3DPRESENT_PARAMETERS pp{ };
+ pp.BackBufferWidth = clientRect.right; // width is window width
+ pp.BackBufferHeight = clientRect.bottom; // height is window height
+ pp.BackBufferFormat = displayMode.Format; // use adapter format
+ pp.BackBufferCount = 1; // 1 back buffer (default)
+ pp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard after presentation
+ pp.hDeviceWindow = hWnd; // associated window handle
+ pp.Windowed = true; // display in window mode
+ pp.Flags = 0; // no special flags
+ // Variable to store results of methods to check if everything succeded.
+ HRESULT result{ };
+ result = _d3d->CreateDevice(D3DADAPTER_DEFAULT, // use default graphics card
+ D3DDEVTYPE_HAL, // use hardware acceleration
+ hWnd, // the window handle
+ D3DCREATE_HARDWARE_VERTEXPROCESSING,
+ // vertices are processed by the hardware
+ &pp, // the present parameters
+ &_device); // struct to store the device
+ // Return false if the device creation failed.
+ // It is helpful to set breakpoints at the return line.
+ if (FAILED(result))
+ return false;
+ // Create a viewport which hold information about which region to draw to.
+ D3DVIEWPORT9 viewport{ };
+ viewport.X = 0; // start at top left corner
+ viewport.Y = 0; // ..
+ viewport.Width = clientRect.right; // use the entire window
+ viewport.Height = clientRect.bottom; // ..
+ viewport.MinZ = 0.0f; // minimun view distance
+ viewport.MaxZ = 100.0f; // maximum view distance
+ // Apply the created viewport.
+ result = _device->SetViewport(&viewport);
+ // Always check if something failed.
+ if (FAILED(result))
+ return false;
+ // Everything was successful, return true.
+ return true;
+}
+// ...
+// Back in our WinMain function we call our initialization function.
+// ...
+// Check if Direct3D initialization succeded, else exit the application.
+if (!InitD3D(hWnd))
+ return -1;
+
+MSG msg{ };
+while (_running) {
+ while (PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ // Clear to render target to a specified color.
+ _device->Clear(0, // number of rects to clear
+ nullptr, // indicates to clear the entire window
+ D3DCLEAR_TARGET, // clear all render targets
+ D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f }, // color (red)
+ 0.0f, // depth buffer clear value
+ 0); // stencil buffer clear value
+ // ...
+ // Drawing operations go here.
+ // ...
+ // Flip the front- and backbuffer.
+ _device->Present(nullptr, // no source rectangle
+ nullptr, // no destination rectangle
+ nullptr, // don't change the current window handle
+ nullptr); // pretty much always nullptr
+}
+// ...
+```
+
+Now the window should be displayed in a bright red color.
+
+## Vertex Buffer
+
+Let's create a vertex buffer to store the vertices for our triangle
+
+```cpp
+// At the top of the file we need to add a include.
+#include <vector>
+// First we declare a new ComPtr holding a vertex buffer.
+ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
+// Lets define a funtion to calculate the byte size of a std::vector
+template <typename T>
+unsigned int GetByteSize(const std::vector<T>& vec) {
+ return sizeof(vec[0]) * vec.size();
+}
+// Define "flexible vertex format" describing the content of our vertex struct.
+// Use the defined color as diffuse color.
+const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
+// Define a struct representing the vertex data the buffer will hold.
+struct VStruct {
+ float x, y, z; // store the 3D position
+ D3DCOLOR color; // store a color
+};
+// Declare a new function to create a vertex buffer.
+IDirect3DVertexBuffer9* CreateBuffer(const std::vector<VStruct>& vertices) {
+ // Declare the buffer to be returned.
+ IDirect3DVertexBuffer9* buffer{ };
+ HRESULT result{ };
+ result = _device->CreateVertexBuffer(
+ GetByteSize(vertices), // vector size in bytes
+ 0, // data usage
+ VertexStructFVF, // FVF of the struct
+ D3DPOOL_DEFAULT, // use default pool for the buffer
+ &buffer, // receiving buffer
+ nullptr); // special shared handle
+ // Check if buffer was created successfully.
+ if (FAILED(result))
+ return nullptr;
+ // Create a data pointer for copying the vertex data
+ void* data{ };
+ // Lock the buffer to get a buffer for data storage.
+ result = buffer->Lock(0, // byte offset
+ GetByteSize(vertices), // size to lock
+ &data, // receiving data pointer
+ 0); // special lock flags
+ // Check if buffer was locked successfully.
+ if (FAILED(result))
+ return nullptr;
+ // Copy the vertex data using C standard libraries memcpy.
+ memcpy(data, vertices.data(), GetByteSize(vertices));
+ buffer->Unlock();
+ // Set the FVF Direct3D uses for rendering.
+ _device->SetFVF(VertexStructFVF);
+ // If everything was successful return the filled vertex buffer.
+ return buffer;
+}
+```
+
+In our **WinMain** we can now call the new function after the Direct3D initialization.
+
+```cpp
+// ...
+if (!InitD3D(hWnd))
+ return -1;
+// Define the vertices we need to draw a triangle.
+// Values are declared in a clockwise direction else Direct3D would cull them.
+// If you want to diable culling just call:
+// _device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+std::vector<VStruct> vertices {
+ // Bottom left
+ VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
+ // Top left
+ VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
+ // Top right
+ VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } }
+};
+// Try to create the vertex buffer else exit the application.
+if (!(_vertexBuffer = CreateBuffer(vertices)))
+ return -1;
+// ...
+```
+
+## Transformations
+
+Before we can use the vertex buffer to draw our primitives, we first need to set up the matrices.
+
+```cpp
+// Lets create a new funtions for the matrix transformations.
+bool SetupTransform() {
+ // Create a view matrix that transforms world space to
+ // view space.
+ D3DXMATRIX view{ };
+ // Use a left-handed coordinate system.
+ D3DXMatrixLookAtLH(
+ &view, // receiving matrix
+ &D3DXVECTOR3{ 0.0f, 0.0f, -20.0f }, // "camera" position
+ &D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, // position where to look at
+ &D3DXVECTOR3{ 0.0f, 1.0f, 0.0f }); // positive y-axis is up
+ HRESULT result{ };
+ result = _device->SetTransform(D3DTS_VIEW, &view); // apply the view matrix
+ if (FAILED(result))
+ return false;
+ // Create a projection matrix that defines the view frustrum.
+ // It transforms the view space to projection space.
+ D3DXMATRIX projection{ };
+ // Create a perspective projection using a left-handed coordinate system.
+ D3DXMatrixPerspectiveFovLH(
+ &projection, // receiving matrix
+ D3DXToRadian(60.0f), // field of view in radians
+ 1024.0f / 768.0f, // aspect ratio (width / height)
+ 0.0f, // minimum view distance
+ 100.0f); // maximum view distance
+ result = _device->SetTransform(D3DTS_PROJECTION, &projection);
+ if (FAILED(result))
+ return false;
+ // Disable lighting for now so we can see what we want to render.
+ result = _device->SetRenderState(D3DRS_LIGHTING, false);
+ // View and projection matrix are successfully applied, return true.
+ return true;
+}
+// ...
+// Back in the WinMain function we can now call the transformation function.
+// ...
+if (!(_vertexBuffer = CreateVertexBuffer(vertices)))
+ return -1;
+// Call the transformation setup function.
+if (!SetupTransform())
+ return -1;
+// ...
+```
+
+## Rendering
+
+Now that everything is setup we can start drawing our first 2D triangle in 3D space.
+
+```cpp
+// ...
+if (!SetupTransform())
+ return -1;
+// First we have to bind our vertex buffer to the data stream.
+HRESULT result{ };
+result = _device->SetStreamSource(0, // use the default stream
+ _vertexBuffer.Get(), // pass the vertex buffer
+ 0, // no offset
+ sizeof(VStruct)); // size of vertex struct
+if (FAILED(result))
+ return -1;
+
+// Create a world transformation matrix and set it to an identity matrix.
+D3DXMATRIX world{ };
+D3DXMatrixIdentity(&world);
+// Create a scalation matrix scaling our primitve by 10 in the x,
+// 10 in the y and keeping the z direction.
+D3DXMATRIX scaling{ };
+D3DXMatrixScaling(&scaling, // matrix to scale
+ 10, // x scaling
+ 10, // y scaling
+ 1); // z scaling
+// Create a rotation matrix storing the current rotation of our primitive.
+// We set the current rotation matrix to an identity matrix for now.
+D3DXMATRIX rotation{ };
+D3DXMatrixIdentity(&rotation);
+// Now we multiply the scalation and rotation matrix and store the result
+// in the world matrix.
+D3DXMatrixMultiply(&world, // destination matrix
+ &scaling, // matrix 1
+ &rotation); // matrix 2
+// Apply the current world matrix.
+_device->SetTransform(D3DTS_WORLD, &world);
+// Disable culling so we can see the back of our primitive when it rotates.
+_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+// The default cullmode is D3DCULL_CW.
+// After we used our the rotation matrix for multiplication we can set it
+// to rotate a small amount.
+// D3DXToRadian() function converts degree to radians.
+D3DXMatrixRotationY(&rotation, // matrix to rotate
+ D3DXToRadian(0.5f)); // rotation angle in radians
+
+MSG msg{ };
+ while (_running) {
+ // ...
+ _device->Clear(0, nullptr, D3DCLEAR_TARGET,
+ D3DXCOLOR{ 0.0f, 0.0f, 0.0f, 1.0f }, 0.0f, 0);
+ // With everything setup we can call the draw function.
+ _device->BeginScene();
+ _device->DrawPrimitive(D3DPT_TRIANGLELIST, // primitive type
+ 0, // start vertex
+ 1); // primitive count
+ _device->EndScene();
+
+ _device->Present(nullptr, nullptr, nullptr, nullptr);
+ // We can keep multiplying the world matrix with our rotation matrix
+ // to add it's rotation to the world matrix.
+ D3DXMatrixMultiply(&world, &world, &rotation);
+ // Update the modified world matrix.
+ _device->SetTransform(D3DTS_WORLD, &world);
+ // ...
+```
+
+You should now be viewing a 10x10 units colored triangle from 20 units away, rotating around its origin.<br>
+You can find the complete working code here: [DirectX - 1](https://pastebin.com/YkSF2rkk)
+
+## Indexing
+
+To make it easier to draw primitives sharing a lot of vertices we can use indexing, so we only have to declare the unique vertices and put the order they are called in another array.
+
+```cpp
+// First we declare a new ComPtr for our index buffer.
+ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
+// ...
+// Declare a function creating a index buffer from a std::vector
+IDirect3DIndexBuffer9* CreateIBuffer(std::vector<unsigned int>& indices) {
+ IDirect3DIndexBuffer9* buffer{ };
+ HRESULT result{ };
+ result = _device->CreateIndexBuffer(
+ GetByteSize(indices), // vector size in bytes
+ 0, // data usage
+ D3DFMT_INDEX32, // format is 32 bit int
+ D3DPOOL_DEFAULT, // default pool
+ &buffer, // receiving buffer
+ nullptr); // special shared handle
+ if (FAILED(result))
+ return nullptr;
+ // Create a data pointer pointing to the buffer data.
+ void* data{ };
+ result = buffer->Lock(0, // byte offset
+ GetByteSize(indices), // byte size
+ &data, // receiving data pointer
+ 0); // special lock flag
+ if (FAILED(result))
+ return nullptr;
+ // Copy the index data and unlock after copying.
+ memcpy(data, indices.data(), GetByteSize(indices));
+ buffer->Unlock();
+ // Return the filled index buffer.
+ return buffer;
+}
+// ...
+// In our WinMain we can now change the vertex data and create new index data.
+// ...
+std::vector<VStruct> vertices {
+ VStruct{ -1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 0.0f, 0.0f, 1.0f } },
+ VStruct{ -1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 1.0f, 0.0f, 1.0f } },
+ VStruct{ 1.0f, 1.0f, 1.0f, D3DXCOLOR{ 0.0f, 0.0f, 1.0f, 1.0f } },
+ // Add a vertex for the bottom right.
+ VStruct{ 1.0f, -1.0f, 1.0f, D3DXCOLOR{ 1.0f, 1.0f, 0.0f, 1.0f } }
+};
+// Declare the index data, here we build a rectangle from two triangles.
+std::vector<unsigned int> indices {
+ 0, 1, 2, // the first triangle (b,left -> t,left -> t,right)
+ 0, 2, 3 // the second triangle (b,left -> t,right -> b,right)
+};
+// ...
+// Now we call the "CreateIBuffer" function to create a index buffer.
+// ...
+if (!(_indexBuffer = CreateIBuffer(indices)))
+ return -1;
+// ...
+// After binding the vertex buffer we have to bind the index buffer to
+// use indexed rendering.
+result = _device->SetStreamSource(0, _vertexBuffer.Get(), 0, sizeof(VStruct));
+if (FAILED(result))
+ return -1;
+// Bind the index data to the default data stream.
+result = _device->SetIndices(_indexBuffer.Get())
+if (FAILED(result))
+ return -1;
+// ...
+// Now we replace the "DrawPrimitive" function with an indexed version.
+_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, // primitive type
+ 0, // base vertex index
+ 0, // minimum index
+ indices.size(), // amount of vertices
+ 0, // start in index buffer
+ 2); // primitive count
+// ...
+```
+
+Now you should see a colored rectangle made up of 2 triangles. If you set the primitive count in the "DrawIndexedPrimitive" method to 1 only the first triangle should be rendered and if you set the start of the index buffer to 3 and the primitive count to 1 only the second triangle should be rendered.<br>
+You can find the complete working code here: [DirectX - 2](https://pastebin.com/yWBPWPRG)
+
+## Vertex declaration
+
+Instead of using the old "flexible vertex format" we should use vertex declarations instead, as the FVF declarations get converted to vertex declarations internally anyway.
+
+```cpp
+// First we have to REMOVE the following lines:
+const unsigned long VertexStructFVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;
+// and
+_device->SetFVF(VertexStructFVF);
+// ...
+// We also have to change the vertex buffer creation FVF-flag.
+result = _device->CreateVertexBuffer(
+ GetByteSize(vertices),
+ 0,
+ 0, // <- 0 indicates we use vertex declarations
+ D3DPOOL_DEFAULT,
+ &buffer,
+ nullptr);
+// Next we have to declare a new ComPtr.
+ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
+// ...
+result = _device->SetIndices(_indexBuffer.Get());
+if (FAILED(result))
+ return -1;
+// Now we have to declare and apply the vertex declaration.
+// Create a vector of vertex elements making up the vertex declaration.
+std::vector<D3DVERTEXELEMENT9> vertexDeclDesc {
+ { 0, // stream index
+ 0, // byte offset from the struct beginning
+ D3DDECLTYPE_FLOAT3, // data type (3d float vector)
+ D3DDECLMETHOD_DEFAULT, // tessellator operation
+ D3DDECLUSAGE_POSTION, // usage of the data
+ 0 }, // index (multiples usage of the same type)
+ { 0,
+ 12, // byte offset (3 * sizeof(float) bytes)
+ D3DDECLTYPE_D3DCOLOR,
+ D3DDECLMETHOD_DEFAULT,
+ D3DDECLUSAGE_COLOR,
+ 0 },
+ D3DDECL_END() // marks the end of the vertex declaration
+};
+// After having defined the vector we can create a vertex declaration from it.
+result = _device->CreateVertexDeclaration(
+ vertexDeclDesc.data(), // the vertex element array
+ &_vertexDecl); // receiving pointer
+if (FAILED(result))
+ return -1;
+// Apply the created vertex declaration.
+_device->SetVertexDeclaration(_vertexDecl.Get());
+// ...
+```
+
+## Shader
+
+The maximum shader model for Direct3D 9 is shader model 3.0. Even though every modern graphics card should support it, it is best to check for capabilities.
+
+```cpp
+// ...
+_device->SetVertexDeclaration(_vertexDecl.Get());
+// First we have to request the device capabilities.
+D3DCAPS9 deviceCaps{ };
+_device->GetDeviceCaps(&deviceCaps);
+// Now we check if shader model 3.0 is supported for the vertex shader.
+if (deviceCaps.VertexShaderVersion < D3DVS_VERSION(3, 0))
+ return -1;
+// And the same for the pixel shader.
+if (deviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
+ return -1;
+```
+
+Now that we are sure shader model 3.0 is supported let's create the vertex and pixel shader files.
+DirectX 9 introduced the HLSL (**High Level Shading Language**), a C-like shader language, which
+simplified the shader programming a lot, as you could only write shaders in shader assembly in DirectX 8.
+Let's create a simple vertex- and pixel shader.
+
+**Vertex Shader**
+
+```cpp
+// 3 4x4 float matrices representing the matrices we set in the fixed-function
+// pipeline by using the SetTransform() method.
+float4x4 projectionMatrix;
+float4x4 viewMatrix;
+float4x4 worldMatrix;
+// The input struct to the vertex shader.
+// It holds a 3d float vector for the position and a 4d float vector
+// for the color.
+struct VS_INPUT {
+ float3 position : POSITION;
+ float4 color : COLOR;
+};
+// The output struct of the vertex shader, that is passed to the pixel shader.
+struct VS_OUTPUT {
+ float4 position : POSITION;
+ float4 color : COLOR;
+};
+// The main function of the vertex shader returns the output it sends to the
+// pixel shader and receives it's input as a parameter.
+VS_OUTPUT main(VS_INPUT input) {
+ // Declare a empty struct, that the vertex shader returns.
+ VS_OUTPUT output;
+ // Set the output position to the input position and set
+ // the w-component to 1, as the input position is a 3d vector and
+ // the output position a 4d vector.
+ output.position = float4(input.position, 1.0f);
+ // Multiply the output position step by step with the world, view and
+ // projection matrices.
+ output.position = mul(output.position, worldMatrix);
+ output.position = mul(output.position, viewMatrix);
+ output.position = mul(output.position, projectionMatrix);
+ // Pass the input color unchanged to the pixel shader.
+ output.color = input.color;
+ // Return the output struct to the pixel shader.
+ // The position value is automatically used as the vertex position.
+ return output;
+}
+```
+
+**Pixel Shader**
+
+```cpp
+// The pixel shader input struct must be the same as the vertex shader output!
+struct PS_INPUT {
+ float4 position : POSITION;
+ float4 color : COLOR;
+};
+// The pixel shader simply returns a 4d vector representing the vertex color.
+// It receives it's input as a parameter just like the vertex shader.
+// We have to declare the output semantic as color to it gets interpreted
+// correctly.
+float4 main(PS_INPUT input) : COLOR {
+ return input.color;
+}
+```
+
+For more on semantics: [DirectX - Semantics](https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics#vertex-shader-semantics)
+
+Now we have to do quite some changes to the code.
+
+```cpp
+ComPtr<IDirect3DDevice9> _device{ };
+ComPtr<IDirect3DVertexBuffer9> _vertexBuffer{ };
+ComPtr<IDirect3DIndexBuffer9> _indexBuffer{ };
+ComPtr<IDirect3DVertexDeclaration9> _vertexDecl{ };
+// We have to add a ComPtr for the vertex- and pixel shader, aswell as one
+// for the constants (matrices) in our vertex shader.
+ComPtr<IDirect3DVertexShader9> _vertexShader{ };
+ComPtr<IDirect3DPixelShader9> _pixelShader{ };
+ComPtr<ID3DXConstantTable> _vertexTable{ };
+// Declare the world and rotation matrix as global, because we use them in
+// WinMain and SetupTransform now.
+D3DXMATRIX _worldMatrix{ };
+D3DXMATRIX _rotationMatrix{ };
+// ...
+bool SetupTransform() {
+ // Set the world and rotation matrix to an identity matrix.
+ D3DXMatrixIdentity(&_worldMatrix);
+ D3DXMatrixIdentity(&_rotationMatrix);
+
+ D3DXMATRIX scaling{ };
+ D3DXMatrixScaling(&scaling, 10, 10, 1);
+ D3DXMatrixMultiply(&_worldMatrix, &scaling, &_rotationMatrix);
+ // After multiplying the scalation and rotation matrix the have to pass
+ // them to the shader, by using a method from the constant table
+ // of the vertex shader.
+ HRESULT result{ };
+ result = _vertexTable->SetMatrix(
+ _device.Get(), // direct3d device
+ "worldMatrix", // matrix name in the shader
+ &_worldMatrix); // pointer to the matrix
+ if (FAILED(result))
+ return false;
+
+ D3DXMATRIX view{ };
+ D3DXMatrixLookAtLH(&view, &D3DXVECTOR3{ 0.0f, 0.0f, -20.0f },
+ &D3DXVECTOR3{ 0.0f, 0.0f, 0.0f }, &D3DXVECTOR3{ 0.0f, 1.0f, 0.0f });
+ // Do the same for the view matrix.
+ result = _vertexTable->SetMatrix(
+ _device.Get(), // direct 3d device
+ "viewMatrix", // matrix name
+ &view); // matrix
+ if (FAILED(result))
+ return false;
+
+ D3DXMATRIX projection{ };
+ D3DXMatrixPerspectiveFovLH(&projection, D3DXToRadian(60.0f),
+ 1024.0f / 768.0f, 0.0f, 100.0f);
+ // And also for the projection matrix.
+ result = _vertexTable->SetMatrix(
+ _device.Get(),
+ "projectionMatrix",
+ &projection);
+ if (FAILED(result))
+ return false;
+
+ D3DXMatrixRotationY(&_rotationMatrix, D3DXToRadian(0.5f));
+ return true;
+}
+// ...
+// Vertex and index buffer creation aswell as initialization stay unchanged.
+// ...
+// After checking that shader model 3.0 is available we have to compile and
+// create the shaders.
+// Declare two temporary buffers storing the compiled shader code.
+ID3DXBuffer* vertexShaderBuffer{ };
+ID3DXBuffer* pixelShaderBuffer{ };
+result = D3DXCompileShaderFromFile("vertex.hlsl", // shader name
+ nullptr, // macro definitions
+ nullptr, // special includes
+ "main", // entry point name
+ "vs_3_0", // shader model version
+ 0, // special flags
+ &vertexShaderBuffer, // code buffer
+ nullptr, // error message
+ &_vertexTable); // constant table
+if (FAILED(result))
+ return -1;
+// After the vertex shader compile the pixel shader.
+result = D3DXCompileShaderFromFile("pixel.hlsl",
+ nullptr,
+ nullptr,
+ "main",
+ "ps_3_0", // pixel shader model 3.0
+ 0,
+ &pixelShaderBuffer,
+ nullptr,
+ nullptr); // no need for a constant table
+if (FAILED(result))
+ return -1;
+// Create the vertex shader from the code buffer.
+result = _device->CreateVertexShader(
+ (DWORD*)vertexShaderBuffer->GetBufferPointer(), // code buffer
+ &_vertexShader); // vertex shader pointer
+if (FAILED(result))
+ return -1;
+
+result = _device->CreatePixelShader(
+ (DWORD*)pixelShaderBuffer->GetBufferPointer(),
+ &_pixelShader);
+if (FAILED(result))
+ return -1;
+// Release the temporary code buffers after the shaders are created.
+vertexShaderBuffer->Release();
+pixelShaderBuffer->Release();
+// Apply the vertex- and pixel shader.
+_device->SetVertexShader(_vertexShader.Get());
+_device->SetPixelShader(_pixelShader.Get());
+// Apply the transform after the shaders have been set.
+if (!SetupTransform())
+ return -1;
+// You can also REMOVE the call so set the lighting render state.
+_device->SetRenderState(D3DRS_LIGHTING, false);
+```
+
+You can find the complete code here: [DirectX - 3](https://pastebin.com/y4NrvawY)
+
+## Texturing
+
+```cpp
+// First we need to declare a ComPtr for the texture.
+ComPtr<IDirect3DTexture9> _texture{ };
+// Then we have to change the vertex struct.
+struct VStruct {
+ float x, y, z;
+ float u, v; // Add texture u and v coordinates
+ D3DCOLOR color;
+};
+// In the vertex declaration we have to add the texture coordinates.
+// the top left of the texture is u: 0, v: 0.
+std::vector<VStruct> vertices {
+ VStruct{ -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, ... }, // bottom left
+ VStruct{ -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, ... }, // top left
+ VStruct{ 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, ... }, // top right
+ VStruct{ 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, ... } // bottom right
+};
+// Next is the vertex declaration.
+std::vector<D3DVERTEXELEMENT9> vertexDecl{
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ // Add a 2d float vector used for texture coordinates.
+ {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ // The color offset is not (3 + 2) * sizeof(float) = 20 bytes
+ {0, 20, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ D3DDECL_END()
+};
+// Now we have to load the texture and pass its to the shader.
+// ...
+_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+// Create a Direct3D texture from a png file.
+result = D3DXCreateTextureFromFile(_device.Get(), // direct3d device
+ "texture.png", // texture path
+ &_texture); // receiving texture pointer
+if (FAILED(result))
+ return -1;
+// Attach the texture to shader stage 0, which is equal to texture register 0
+// in the pixel shader.
+_device->SetTexture(0, _texture.Get());
+```
+
+With the main code ready we now have to adjust the shaders to these changes.
+
+**Vertex Shader**
+
+```cpp
+float4x4 projectionMatrix;
+float4x4 viewMatrix;
+float4x4 worldMatrix;
+// Add the texture coordinates to the vertex shader in- and output.
+struct VS_INPUT {
+ float3 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+struct VS_OUTPUT {
+ float4 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+VS_OUTPUT main(VS_INPUT input) {
+ VS_OUTPUT output;
+
+ output.position = float4(input.position, 1.0f);
+ output.position = mul(output.position, worldMatrix);
+ output.position = mul(output.position, viewMatrix);
+ output.position = mul(output.position, projectionMatrix);
+
+ output.color = input.color;
+ // Set the texcoord output to the input.
+ output.texcoord = input.texcoord;
+
+ return output;
+}
+```
+
+**Pixel Shader**
+
+```cpp
+// Create a sampler called "sam0" using sampler register 0, which is equal
+// to the texture stage 0, to which we passed the texture.
+sampler sam0 : register(s0);
+
+struct PS_INPUT {
+ float4 position : POSITION;
+ float2 texcoord : TEXCOORD;
+ float4 color : COLOR;
+};
+
+float4 main(PS_INPUT input) : COLOR{
+ // Do a linear interpolation between the texture color and the input color
+ // using 75% of the input color.
+ // tex2D returns the texture data at the specified texture coordinate.
+ return lerp(tex2D(sam0, input.texcoord), input.color, 0.75f);
+}
+```
+
+## Quotes
+<sup>[1]</sup>[DirectX - Wikipedia](https://en.wikipedia.org/wiki/DirectX)
diff --git a/mercury.html.markdown b/mercury.html.markdown
new file mode 100644
index 00000000..f749bac4
--- /dev/null
+++ b/mercury.html.markdown
@@ -0,0 +1,263 @@
+---
+language: mercury
+contributors:
+ - ["Julian Fondren", "https://mercury-in.space/"]
+---
+
+Mercury is a strict, pure functional/logic programming language, with
+influences from Prolog, ML, and Haskell.
+
+```prolog
+% Percent sign starts a one-line comment.
+
+ % foo(Bar, Baz)
+ %
+ % Documentation comments are indented before what they describe.
+:- pred foo(bar::in, baz::out) is det.
+
+% All toplevel syntax elements end with a '.' -- a full stop.
+
+% Mercury terminology comes from predicate logic. Very roughly:
+
+% | Mercury | C |
+% | | |
+% | Goal | statement |
+% | expression | expression |
+% | predicate rule | void function |
+% | function rule | function |
+% | head (of a rule) | function name and parameters |
+% | body (of a rule) | function body |
+% | fact | (rule without a body) |
+% | pred/func declaration | function signature |
+% | A, B (conjunction) | A && B |
+% | A ; B (disjunction) | if (A) {} else if (B) {} |
+
+% some facts:
+man(socrates). % "it is a fact that Socrates is a man"
+man(plato).
+man(aristotle).
+
+% a rule:
+mortal(X) :- man(X). % "It is a rule that X is a mortal if X is a man."
+% ^^^^^^-- the body of the rule
+% ^^-- an arrow <--, pointing to the head from the body
+%^^^^^^^^-- the head of the rule
+% this is also a single clause that defines the rule.
+
+% that X is capitalized is how you know it's a variable.
+% that socrates is uncapitalized is how you know it's a term.
+
+% it's an error for 'socrates' to be undefined. It must have a type:
+
+% declarations begin with ':-'
+:- type people
+ ---> socrates
+ ; plato
+ ; aristotle
+ ; hermes.
+ %<--first tab stop (using 4-space tabs)
+ %<--third tab stop (first after --->)
+
+:- pred man(people). % rules and facts also require types
+
+% a rule's modes tell you how it can be used.
+:- mode man(in) is semidet. % man(plato) succeeds. man(hermes) fails.
+:- mode man(out) is multi. % man(X) binds X to one of socrates ; plato ; aristotle
+
+% a semidet predicate is like a test. It doesn't return a value, but
+% it can succeed or fail, triggering backtracking or the other side of
+% a disjunction or conditional.
+
+% 'is semidet' provides the determinism of a mode. Other determinisms:
+% | Can fail? | 0 solutions | 1 | more than 1 |
+% | | | | |
+% | no | erroneous | det | multi |
+% | yes | failure | semidet | nondet |
+
+:- pred mortal(people::in) is semidet. % type/mode in one declaration
+
+% this rule's body consists of two conjunctions: A, B, C
+% this rule is true if A, B, and C are all true.
+% if age(P) returns 16, it fails.
+% if alive(P) fails, it fails.
+:- type voter(people::in) is semidet.
+voter(P) :-
+ alive(P),
+ registered(P, locale(P)),
+ age(P) >= 18. % age/1 is a function; int.>= is a function used as an operator
+
+% "a P is a voter if it is alive, is registered in P's locale, and if
+% P's age is 18 or older."
+
+% the >= used here is provided by the 'int' module, which isn't
+% imported by default. Mercury has a very small 'Prelude' (the
+% 'builtin' module). You even need to import the 'list' module if
+% you're going to use list literals.
+```
+
+Complete runnable example. File in 'types.m'; compile with 'mmc --make types'.
+
+```prolog
+:- module types.
+:- interface.
+:- import_module io. % required for io.io types in...
+% main/2 is usually 'det'. threading and exceptions require 'cc_multi'
+:- pred main(io::di, io::uo) is cc_multi. % program entry point
+:- implementation.
+:- import_module int, float, string, list, bool, map, exception.
+
+% enum.
+:- type days
+ ---> sunday
+ ; monday
+ ; tuesday
+ ; wednesday
+ ; thursday
+ ; friday
+ ; saturday.
+
+% discriminated union, like datatype in ML.
+:- type payment_method
+ ---> cash(int)
+ ; credit_card(
+ name :: string, % named fields
+ cc_number :: string,
+ cvv :: int,
+ expiration :: string
+ )
+ ; crypto(coin_type, wallet, amount).
+
+:- type coin_type
+ ---> etherium
+ ; monero. % "other coins are available"
+
+% type aliases.
+:- type wallet == string.
+:- type amount == int.
+
+% !IO is the pair of io.io arguments
+% pass it to anything doing I/O, in order to perform I/O.
+% many otherwise-impure functions can 'attach to the I/O state' by taking !IO
+main(!IO) :-
+ Ints = [
+ 3,
+ 1 + 1,
+ 8 - 1,
+ 10 * 2,
+ 35 / 5,
+ 5 / 2, % truncating division
+ int.div(5, 2), % floored division
+ div(5, 2), % (module is unambiguous due to types)
+ 5 `div` 2, % (any binary function can be an operator with ``)
+ 7 `mod` 3, % modulo of floored division
+ 7 `rem` 3, % remainder of truncating division
+ 2 `pow` 4, % 2 to the 4th power
+ (1 + 3) * 2, % parens have their usual meaning
+
+ 2 >> 3, % bitwise right shift
+ 128 << 3, % bitwise left shift
+ \ 0, % bitwise complement
+ 5 /\ 1, % bitwise and
+ 5 \/ 1, % bitwise or
+ 5 `xor` 3, % bitwise xor
+
+ max_int,
+ min_int,
+
+ 5 `min` 3, % ( if 5 > 3 then 3 else 5 )
+ 5 `max` 3
+ ],
+ Bools = [
+ yes,
+ no
+ % bools are much less important in Mercury because control flow goes by
+ % semidet goals instead of boolean expressions.
+ ],
+ Strings = [
+ "this is a string",
+ "strings can have "" embedded doublequotes via doubling",
+ "strings support \u4F60\u597D the usual escapes\n",
+ % no implicit concatenation of strings: "concat:" "together"
+ "but you can " ++ " use the string.++ operator",
+
+ % second param is a list(string.poly_type)
+ % s/1 is a function that takes a string and returns a poly_type
+ % i/1 takes an int. f/1 takes a float. c/1 takes a char.
+ string.format("Hello, %d'th %s\n", [i(45), s("World")])
+ ],
+
+ % start with purely functional types like 'map' and 'list'!
+ % arrays and hash tables are available too, but using them
+ % requires knowing a lot more about Mercury
+ get_map1(Map1),
+ get_map2(Map2),
+
+ % list.foldl has *many* variations
+ % this one calls io.print_line(X, !IO) for each X of the list
+ foldl(io.print_line, Ints, !IO),
+ foldl(io.print_line, Bools, !IO),
+ foldl(io.print_line, Strings, !IO),
+ io.print_line(Map1, !IO),
+ % ( if Cond then ThenGoal else ElseGoal )
+ % I/O not allowed in Cond: I/O isn't allowed to fail!
+ ( if Map2^elem(42) = Elem then
+ io.print_line(Elem, !IO)
+ else % always required
+ true % do nothing, successfully (vs. 'fail')
+ ),
+
+ % exception handling:
+ ( try [io(!IO)] ( % io/1 param required or no I/O allowed here
+ io.print_line(received(cash(1234)), !IO),
+ io.print_line(received(crypto(monero, "invalid", 123)), !IO)
+ ) then
+ io.write_string("all payments accepted\n", !IO) % never reached
+ catch "monero not yet supported" -> % extremely specific catch!
+ io.write_string("monero payment failed\n", !IO)
+ ).
+
+:- pred get_map1(map(string, int)::out) is det.
+get_map1(!:Map) :- % !:Map in the head is the final (free, unbound) Map
+ !:Map = init, % !:Map in the body is the next Map
+ det_insert("hello", 1, !Map), % pair of Map vars
+ det_insert("world", 2, !Map),
+
+ % debug print of current (bound) Map
+ % other [Params] can make it optional per runtime or compiletime flags
+ trace [io(!IO)] (io.print_line(!.Map, !IO)),
+
+ det_insert_from_corresponding_lists(K, V, !Map),
+ % this code is reordered so that K and V and defined prior to their use
+ K = ["more", "words", "here"],
+ V = [3, 4, 5].
+
+:- pred get_map2(map(int, bool)::out) is det.
+get_map2(Map) :-
+ det_insert(42, yes, map.init, Map).
+
+:- func received(payment_method) = string.
+received(cash(N)) = string.format("received %d dollars", [i(N)]).
+received(credit_card(_, _, _, _)) = "received credit card". % _ is throwaway
+received(crypto(Type, _Wallet, Amount)) = S :- % _Wallet is named throwaway
+ ( % case/switch structure
+ Type = etherium,
+ S = string.format("receiving %d ETH", [i(Amount)])
+ ;
+ Type = monero,
+ throw("monero not yet supported") % exception with string as payload
+ ).
+```
+
+## That was quick! Want more?
+
+### More Tutorials
+
+* [Mercury Tutorial](https://mercurylang.org/documentation/papers/book.pdf) (pdf link) - a more traditional tutorial with a more relaxed pace
+* [Mercury Crash Course](https://mercury-in.space/crash.html) - a dense example-driven tutorial with Q&A format
+* [Github Wiki Tutorial](https://github.com/Mercury-Language/mercury/wiki/Tutorial)
+* [Getting Started with Mercury](https://bluishcoder.co.nz/2019/06/23/getting-started-with-mercury.html) - installation and your first steps
+
+### Documentation
+
+* Language manual, user's guide, and library reference are all at
+ [mercurylang.org](https://mercurylang.org/documentation/documentation.html)
diff --git a/tr-tr/clojure-tr.html.markdown b/tr-tr/clojure-tr.html.markdown
index 64970945..5ebe5ce6 100644
--- a/tr-tr/clojure-tr.html.markdown
+++ b/tr-tr/clojure-tr.html.markdown
@@ -4,6 +4,7 @@ lang: tr-tr
filename: learnclojure-tr.clj
contributors:
- ["Adam Bard", "http://adambard.com/"]
+ - ["Seçkin KÜKRER", "https://leavenha.github.io"]
translators:
- ["Seçkin KÜKRER", "https://leavenha.github.io"]
---
diff --git a/tr-tr/edn-tr.html.markdown b/tr-tr/edn-tr.html.markdown
new file mode 100644
index 00000000..9a2ac1ff
--- /dev/null
+++ b/tr-tr/edn-tr.html.markdown
@@ -0,0 +1,157 @@
+---
+language: edn
+filename: learnedn-tr.edn
+lang: tr-tr
+contributors:
+ - ["Seçkin KÜKRER", "https://github.com/LeaveNhA"]
+---
+
+# Y = 20 Dakika.
+
+### Genişletilebilir Veri Notasyonu (EDN, Extensible Data Notation).
+
+### Okunuşu: (Türkçe: ey-di-en), (English: eed-n)
+
+### Kodlama Türü: UTF-8
+
+EDN Clojure sözdiziminin bir alt kümesidir. Bu alt küme, amacı gereği kod barındırmaz. Ve kendisi bir tip sistemi değildir. Bir şeması da yoktur. En basit tabirle; Genişletilebilir Veri Notasyonu kabul edilebilir elemanların bir kümesidir.
+
+EDN elementleri, akışları ve dosyaları UTF-8 kullanılarak kodlanmalıdır. Üstelik, dökümanı çevreleyen işaretçiler de olmadığı için akış, dağıtık programlama mesaj arayüzü ve diğer dinamik sistemler için idealdir.
+
+
+```clojure
+; Yorumlar, yorumlarımız, noktalı virgül ile başlıyor.
+;; Genellikle ikili olarak kullanılıyorlar.
+
+;; |--------------------------------|
+; |--------- Genel Yapısı ---------|
+;; |--------------------------------|
+
+;; Boşluklar --whitespaces--, elementler için en yaygın ayıraçtır.
+"Mustafa" "Kemal" "ATATÜRK"
+;; Fakat okunuşu arttırdığı gerekçesiyle "," (virgüller --commas--) EDN yorumlayıcısı tarafından görmezden gelinir ve boşluk olarak nitelendirilir.
+"Mustafa","Kemal","PAŞA"
+;; Üstelik bu yenilikçi sözdizimsel kurala rağmen, {}, [] () gibi koleksiyon karakterlerini ayırmak için boşluğa ya da boşluğa çözümlenen virgüle ihtiyacınız yoktur.
+[["MUSTAFA"] ["KEMAL"] [[{"ATA" "ATATÜRK"}]]]
+;; Üst düzey vektör elemanlarını birbirinden ayıran boşlukları da kaldırabilirsiniz.
+;; Fakat bu size, okunması zor bir vektör dışında hiç bir şey vermeyecektir.
+
+;; |--------------------------------|
+; |-------- Atomik Yapılar --------|
+;; |--------------------------------|
+
+; Mantıksal Değerler
+;; Mantıksal Doğru, çoğu teknolojide aynı gösterimi var.
+true
+;; Mantıksal Yanlış.
+false
+
+; Karakter Katarları
+;; Karakter katarları, --SADECE-- çift tırnak ile belirtilebilir.
+"İzmirin dağlarında çiçekler açar!"
+;; C, C++, Java v.b. gibi dillerin desteklediği kaçış sekanslarını da destekler.
+"Altın güneş orda sırmalar saçar.\nBozulmuş düşmanlar yel gibi kaçar."
+;; Kaçış sekansları için bknz: $!$
+
+; Karakter Sabitleri
+;; Karakter sabitleri önlerinde bir ters eğik çizgi ile temsil edilirler.
+\T \Ü \R \K
+;; Üstelik, belirli kaçıl sekanslarının da karşılığı Karakter Sabiti olarak var.
+\newline \return
+
+; Anahtar Kelimeler
+;; Anahtar Kelimeler, önlerinde bir ":" iki nokta --colon--
+:yımırta
+:kaşar
+:bıngıl
+
+; Semboller
+;; Semboller tanımlayıcıları temsil etmek için kullanılır.
+;; "/" karakteri, Sembol Sabitlerinde isim-uzayı ayıracı olarak kullanılıyor.
+izmir/kızları
+;; "mutfak" isim uzayındaki "ekmek-bıçağı" isimli sembole çözümlenir.
+
+banyo/fayans
+parke
+laminat
+
+; Sayısal Değerler
+;; Tam Sayı sabiti.
+1991
+;; Kayan Noktalı Sabiti.
+19.67
+
+; Listeler
+;; Listeler, yukarıdaki temel tiplerin ardışıklanmasıdır.
+(bomba :bomba nokta \c \o \m)
+
+; Vektörler
+;; Vektörler bir bakıma Listelere benzeseler de, bir çok açıdan farklıdırlar.
+;; Mesela Listenin aksine Vektörler, Rastgele Erişime imkan verir.
+[[] "şimdi" "asker"]
+
+; Eşlemeler
+;; Sıfır veya daha fazla Anahtar-Değer çifti kabul eder.
+;; Not: Clojure Veri Yapıları Soyutlaması ile Eşlemeler de, teknik olarak ardışık olarak işlenebilir.
+{:canı :neler-ister?
+ :uykuda "mevlam"}
+;; Bu ve diğer tüm Veri Yapıları Homojendir, birbirilerini barındırabilir, kapsayabilir, içerebilirler.
+;; Ayrıca okunurluk gibi farklı sebeplerle virgül kullanımında özgürsünüz.
+{{:id_ "129u391824981237981237" :kim "BEN"}, göster!}
+
+; Kümeler
+;; Kümeler eşsiz eleman barındıran bir yapıdır.
+;; Matematikteki karşılığını veriyor dersek yanlış olmaz.
+#{:sen 3 milyar 750 milyon}
+
+;; |--------------------------------|
+; |------ Etiketli Elemanlar ------|
+;; |--------------------------------|
+
+;; EDN (Genişletilebilir Veri Notasyonu), # sembolü ile genişletilebilir.
+
+#benimuygulamam/bağlantı {:içerik "Y dakikada EDN Öğren" :url "https://learnxinyminutes.com/docs/tr-tr/edn-tr" :tıhlama-aksiyonu yırrttılll!}
+
+;; Ve bu yapıyı yorumlayacak bir de yapı gerekiyor.
+(defn ->bağlantı [props]
+ (str "<a href='" (:url props) "'" ">"
+ (:içerik props)
+ "</a>"))
+
+;; Bu örnekte yorumlayıcıya, basit bir fonksiyon veriyoruz.
+;; `clojure.edn/read-string` aslında bir ayarlar Eşlemesi kabul ediyor.
+;; (Bu tür fonksiyon genişlemeleri, Clojure ekosisteminde yaygındır.)
+
+(clojure.edn/read-string
+ {:readers {'benimuygulamam/bağlantı ->bağlantı}}
+ "#benimuygulamam/bağlantı {:içerik \"Y dakikada EDN Öğren\" :url \"https://learnxinyminutes.com/docs/tr-tr/edn-tr\" :tıhlama-aksiyonu yırrttılll!}")
+;=> "<a href='https://learnxinyminutes.com/docs/tr-tr/edn-tr'>Y dakikada EDN Öğren</a>"
+
+;; |--------------------------------|
+; |--- Ön Tanımlı Genişletmeler ---|
+;; |--------------------------------|
+
+; Tarih Etiketi
+;; Bu etiket `inst` ön-ekinden sonra bir RFC-3339 formatında bir karakter katarı beklemektedir.
+#inst "2013-10-21T14:50:00+00:00" ; => Formatlanmış bir şekilde: 21/10/2013 14:50:00
+
+; UUID Etiketi
+;; Bu etiket `uuid` ön-ekinden sonra bir UUID karşılığını karakter katarı olarak kabul eder.
+#uuid "11k12fae-7d3c-11k0-a765-0010ckke6hgk"
+
+```
+
+# Son Ek
+Bu içerik, EDN'i tanıtmakta kısıtlı bir açıyla, özet bilgiler sunmaktadır.
+Fakat, Clojure ve diğer Veri Odaklı dillerde, Verinin yolculuğunu anlamak için önemli bir rol oynamaktadır.
+EDN'in var olan probleme çözümü ve artı/eksilerinin doğru şekilde kavranması mühimdir.
+Ben bu dökümanı hazırlarken, EDN ve gerçek dünya kullanımını anlatan yoktu. Fakat ümidim, Clojure ve diğer teknolojiler üzerinde kullanımının artmasından sonra birinin bu ihtiyacı giderecek özgün kaynak çıkarmasıdır.
+
+Başarılar!
+
+# Referanslar
+
+- [EDN Formatı Standardı](https://github.com/edn-format/edn)
+- [Gerçeklemeler](https://github.com/edn-format/edn/wiki/Implementations)
+- [Etiketlenmiş Elementler](http://www.compoundtheory.com/clojure-edn-walkthrough/)
+- [Clojure.Docs EDN İçeriği](https://clojuredocs.org/clojure.edn)