From bd2d04caee734687730c6f58f9c03ba03eb579a3 Mon Sep 17 00:00:00 2001 From: Kapendev Date: Tue, 5 Mar 2024 07:59:55 +0200 Subject: [PATCH] First. --- .gitignore | 16 + LICENSE | 21 + README.md | 29 + TODO.md | 6 + basic.d | 13 + core/ascii.d | 100 ++ core/basic.d | 20 + core/color.d | 48 + core/container.d | 419 +++++++++ core/fmt.d | 78 ++ core/io.d | 50 + core/math.d | 488 ++++++++++ core/strconv.d | 279 ++++++ core/strutils.d | 149 +++ core/sumtype.d | 82 ++ dub.json | 10 + game/basic.d | 13 + game/dialogue.d | 86 ++ game/engine.d | 838 +++++++++++++++++ vendor/ray/raylib.d | 1695 ++++++++++++++++++++++++++++++++++ vendor/ray/raymath.d | 678 ++++++++++++++ vendor/ray/rlgl.d | 2052 ++++++++++++++++++++++++++++++++++++++++++ 22 files changed, 7170 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 TODO.md create mode 100644 basic.d create mode 100644 core/ascii.d create mode 100644 core/basic.d create mode 100644 core/color.d create mode 100644 core/container.d create mode 100644 core/fmt.d create mode 100644 core/io.d create mode 100644 core/math.d create mode 100644 core/strconv.d create mode 100644 core/strutils.d create mode 100644 core/sumtype.d create mode 100644 dub.json create mode 100644 game/basic.d create mode 100644 game/dialogue.d create mode 100644 game/engine.d create mode 100644 vendor/ray/raylib.d create mode 100644 vendor/ray/raymath.d create mode 100644 vendor/ray/rlgl.d diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6aebf5d --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +.dub +docs.json +__dummy.html +docs/ +/popka +popka.so +popka.dylib +popka.dll +popka.a +popka.lib +popka-test-* +*.exe +*.pdb +*.o +*.obj +*.lst diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..48662a6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Alexandros F. G. Kapretsos + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..30e1db1 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# 🍂 Popka + +Popka is a lightweight and beginner-friendly 2D game engine for the D programming language. +It focuses on providing a simple and easy-to-understand foundation for building 2D games. +The game engine is currently under development and is not yet ready for use. + +```d +import popka.basic; + +void main() { + openWindow(800, 600); + while (isWindowOpen) { + if (Keyboard.q.isPressed) { + closeWindow(); + } + } + freeWindow(); +} +``` + +## Dependencies + +Popka requires the raylib library to be installed for full functionality. +Please install raylib following the official instructions before using this game engine. + +## License + +The project is released under the terms of the MIT License. +Please refer to the LICENSE file. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..b55c29b --- /dev/null +++ b/TODO.md @@ -0,0 +1,6 @@ +# TODO + +- [ ] Dialogue functionality in dialogue.d must be implemented. +- [ ] Collision functionality must be implemented. +- [ ] Add more parsing options for fmt.d and strconv.d. +- [ ] Write tests. diff --git a/basic.d b/basic.d new file mode 100644 index 0000000..f7efe84 --- /dev/null +++ b/basic.d @@ -0,0 +1,13 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.basic; + +/// The basic module acts as a central hub, +/// bundling together numerous specialized modules +/// to provide an extensive array of tools catering to a variety of programming tasks. + +public import popka.core.basic; +public import popka.game.basic; + +unittest {} diff --git a/core/ascii.d b/core/ascii.d new file mode 100644 index 0000000..ff8a57b --- /dev/null +++ b/core/ascii.d @@ -0,0 +1,100 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.ascii; + +/// The ascii module assists in handling ASCII characters. + +enum { + spaceChars = " \t\v\r\n\f", +} + +bool isLower(char c) { + return c >= 'a' && c <= 'z'; +} + +bool isLower(const(char)[] str) { + foreach (c; str) { + if (!isLower(c)) return false; + } + return true; +} + +bool isUpper(char c) { + return c >= 'A' && c <= 'Z'; +} + +bool isUpper(const(char)[] str) { + foreach (c; str) { + if (!isUpper(c)) return false; + } + return true; +} + +bool isAlpha(char c) { + return isLower(c) || isUpper(c); +} + +bool isAlpha(const(char)[] str) { + foreach (c; str) { + if (!isAlpha(c)) return false; + } + return true; +} + +bool isDigit(char c) { + return c >= '0' && c <= '9'; +} + +bool isDigit(const(char)[] str) { + foreach (c; str) { + if (!isDigit(c)) return false; + } + return true; +} + +bool isSpace(char c) { + foreach (sc; spaceChars) { + if (c == sc) return true; + } + return false; +} + +bool isSpace(const(char)[] str) { + foreach (c; str) { + if (!isSpace(c)) return false; + } + return true; +} + +char toLower(char c) { + return isUpper(c) ? cast(char) (c + 32) : c; +} + +void toLower(char[] str) { + foreach (ref c; str) { + c = toLower(c); + } +} + +char toUpper(char c) { + return isLower(c) ? cast(char) (c - 32) : c; +} + +void toUpper(char[] str) { + foreach (ref c; str) { + c = toUpper(c); + } +} + +char toDigit(char c) { + return isDigit(c) ? cast(char) (c - 48) : '0'; +} + +void toDigit(char[] str) { + foreach (ref c; str) { + c = toDigit(c); + } +} + +unittest {} diff --git a/core/basic.d b/core/basic.d new file mode 100644 index 0000000..f766a2d --- /dev/null +++ b/core/basic.d @@ -0,0 +1,20 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.basic; + +/// The basic module acts as a central hub, +/// bundling together numerous specialized modules +/// to provide an extensive array of tools catering to a variety of programming tasks. + +public import popka.core.ascii; +public import popka.core.color; +public import popka.core.container; +public import popka.core.fmt; +public import popka.core.io; +public import popka.core.math; +public import popka.core.strconv; +public import popka.core.strutils; +public import popka.core.sumtype; + +unittest {} diff --git a/core/color.d b/core/color.d new file mode 100644 index 0000000..94e27cb --- /dev/null +++ b/core/color.d @@ -0,0 +1,48 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.color; + +/// The color module specializes in handling color-related operations, +/// offering a suite of procedures tailored for manipulating and managing color properties within a program. + +enum { + blank = Color(), + black = Color(0), + gray = Color(100), + white = Color(255), + red = Color(255, 0, 0), + green = Color(0, 255, 0), + blue = Color(0, 0, 255), + yellow = Color(255, 255, 0), + magenta = Color(255, 0, 255), + cyan = Color(0, 255, 255), +} + +struct Color { + ubyte r; + ubyte g; + ubyte b; + ubyte a; + + this(ubyte r, ubyte g, ubyte b, ubyte a) { + this.r = r; + this.g = g; + this.b = b; + this.a = a; + } + + this(ubyte r, ubyte g, ubyte b) { + this(r, g, b, 255); + } + + this(ubyte r) { + this(r, r, r, 255); + } + + this(ubyte[4] rgba) { + this(rgba[0], rgba[1], rgba[2], rgba[3]); + } +} + +unittest {} diff --git a/core/container.d b/core/container.d new file mode 100644 index 0000000..1ab5136 --- /dev/null +++ b/core/container.d @@ -0,0 +1,419 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.container; + +/// The container module serves as a hub for various data structures, +/// offering a cohesive set of tools for efficient storage and retrieval of information within a program. + +import lib = core.stdc.stdlib; +import popka.core.fmt; + +struct List(T) { + T[] items; + size_t capacity; + + this(size_t length) { + foreach (i; 0 .. length) { + append(T.init); + } + } + + this(TT)(const(TT)[] args) { + foreach (arg; args) { + append(arg); + } + } + + this(TT)(List!TT list) { + foreach (item; list.items) { + append(item); + } + } + + this(TT)(FlagList!TT list) { + foreach (item; list.items) { + append(item); + } + } + + T[] opSlice(size_t dim)(size_t i, size_t j) { + return items[i .. j]; + } + + T[] opIndex() { + return items[]; + } + + T[] opIndex(T[] slice) { + // D calls this when the slice op is used and it works like this: opIndex(opSlice(i, j)) + return slice; + } + + ref T opIndex(size_t i) { + // Returning a ref will let people take a pointer to that value. + return items[i]; + } + + void opIndexAssign(TT)(TT rhs, size_t i) { + items[i] = rhs; + } + + void opIndexOpAssign(string op, TT)(TT rhs, size_t i) { + mixin("items[i] " ~ op ~ "= rhs;"); + } + + size_t opDollar(size_t dim)() { + return items.length; + } + + size_t length() { + return items.length; + } + + void append(TT)(const(TT)[] args...) { + foreach (arg; args) { + size_t newLength = length + 1; + if (newLength > capacity) { + capacity = findListCapacity(newLength); + items = (cast(T*) lib.realloc(items.ptr, capacity * T.sizeof))[0 .. newLength]; + } else { + items = items.ptr[0 .. newLength]; + } + // We cast here because of the type system. + items[$ - 1] = cast(TT) arg; + } + } + + void remove(size_t i) { + items[i] = items[$ - 1]; + items = items[0 .. $ - 1]; + } + + T pop() { + T temp = items[$ - 1]; + remove(length - 1); + return temp; + } + + void resize(size_t length) { + if (length < this.length) { + items = items[0 .. length]; + } else { + foreach (i; 0 .. length - this.length) { + this.append(T.init); + } + } + } + + void fill(TT)(TT value) { + foreach (ref item; items) { + item = value; + } + } + + void clear() { + items = items[0 .. 0]; + } + + void free() { + if (items.ptr != null) { + lib.free(items.ptr); + items = []; + capacity = 0; + } + } +} + +struct FlagList(T) { + List!T data; + List!bool flags; + size_t hotIndex; + size_t openIndex; + + this(size_t length) { + foreach (i; 0 .. length) { + append(T.init); + } + } + + this(TT)(const(TT)[] args...) { + foreach (arg; args) { + append(arg); + } + } + + this(TT)(List!TT list) { + foreach (item; list.items) { + append(item); + } + } + + this(TT)(FlagList!TT list) { + data.resize(list.data.length); + flags.resize(list.flags.length); + foreach (i; 0 .. flags.length) { + data[i] = list.data[i]; + flags[i] = list.flags[i]; + } + hotIndex = list.hotIndex; + openIndex = list.openIndex; + } + + ref T opIndex(size_t i, const(char)[] file = __FILE__, size_t line = __LINE__) { + if (!flags[i]) { + assert(0, "{}({}): ID {} doesn't exist.".fmt(file, line, i)); + } + return data[i]; + } + + void opIndexAssign(TT)(TT rhs, size_t i) { + data[i] = rhs; + flags[i] = true; + hotIndex = i; + } + + void opIndexOpAssign(string op, TT)(TT rhs, size_t i, const(char)[] file = __FILE__, size_t line = __LINE__) { + if (!flags[i]) { + assert(0, "{}({}): ID {} doesn't exist.".fmt(file, line, i)); + } + mixin("data[i] " ~ op ~ "= rhs;"); + } + + size_t length() { + size_t result = 0; + foreach (id; ids) { + result += 1; + } + return result; + } + + void append(TT)(const(TT)[] args...) { + foreach (arg; args) { + if (openIndex == flags.length) { + data.append(arg); + flags.append(true); + hotIndex = openIndex; + openIndex += 1; + } else { + foreach (i; openIndex .. flags.length) { + if (!flags[i]) { + data[i] = arg; + flags[i] = true; + hotIndex = i; + openIndex = i + 1; + break; + } + } + } + } + } + + void remove(size_t i, const(char)[] file = __FILE__, size_t line = __LINE__) { + if (!flags[i]) { + assert(0, "{}({}): ID {} doesn't exist.".fmt(file, line, i)); + } + flags[i] = false; + hotIndex = i; + if (i < openIndex) { + openIndex = i; + } + } + + void resize(size_t length) { + if (length < flags.length) { + // I could write more code but I don't think that people will really resize. + hotIndex = 0; + openIndex = 0; + } + data.resize(length); + flags.resize(length); + } + + void fill(TT)(TT value) { + data.fill(value); + flags.fill(true); + hotIndex = flags.length - 1; + openIndex = flags.length; + } + + void clear() { + data.clear(); + flags.clear(); + hotIndex = 0; + openIndex = 0; + } + + void free() { + data.free(); + flags.free(); + hotIndex = 0; + openIndex = 0; + } + + auto ids() { + struct Range { + bool[] flags; + size_t id; + + bool empty() { + return id == flags.length; + } + + size_t front() { + return id; + } + + void popFront() { + id += 1; + while (id != flags.length && !flags[id]) { + id += 1; + } + } + } + + size_t id = 0; + while (id < flags.length && !flags[id]) { + id += 1; + } + return Range(flags.items, id); + } + + auto items() { + struct Range { + T[] data; + bool[] flags; + size_t id; + + bool empty() { + return id == flags.length; + } + + ref T front() { + return data[id]; + } + + void popFront() { + id += 1; + while (id != flags.length && !flags[id]) { + id += 1; + } + } + } + + size_t id = 0; + while (id < flags.length && !flags[id]) { + id += 1; + } + return Range(data.items, flags.items, id); + } +} + +size_t findListCapacity(size_t length) { + enum defaultCapacity = 64; + + size_t result = defaultCapacity; + while (result < length) { + result *= 2; + } + return result; +} + +struct Grid(T) { + List!T cells; + float cellWidth; + float cellHeight; + size_t rowCount; + size_t colCount; + + this(size_t rowCount, size_t colCount, size_t cellWidth, size_t cellHeight) { + this.cellWidth = cellWidth; + this.cellHeight = cellHeight; + resize(rowCount, colCount); + } + + this(size_t rowCount, size_t colCount) { + resize(rowCount, colCount); + } + + // TODO: Learn how to slice only rows, ... + T[] opSlice(size_t dim)(size_t i, size_t j) { + return items[i .. j]; + } + + T[] opIndex() { + return cells[]; + } + + T[] opIndex(T[] slice) { + return slice; + } + + ref T opIndex(size_t i) { + return cells[i]; + } + + ref T opIndex(size_t row, size_t col) { + return cells[colCount * row + col]; + } + + void opIndexAssign(TT)(TT rhs, size_t i) { + cells[i] = rhs; + } + + void opIndexAssign(TT)(TT rhs, size_t row, size_t col) { + cells[colCount * row + col] = rhs; + } + + void opIndexOpAssign(string op, TT)(TT rhs, size_t i) { + mixin("cells[i] " ~ op ~ "= rhs;"); + } + + void opIndexOpAssign(string op, TT)(TT rhs, size_t row, size_t col) { + mixin("cells[colCount * row + col] " ~ op ~ "= rhs;"); + } + + size_t opDollar(size_t dim)() { + static if (dim == 0) { + return rowCount; + } else { + return colCount; + } + } + + size_t length() { + return cells.length; + } + + float width() { + return cellWidth * colCount; + } + + float height() { + return cellHeight * rowCount; + } + + void resize(size_t rowCount, size_t colCount) { + this.cells.resize(rowCount * colCount); + this.rowCount = rowCount; + this.colCount = colCount; + } + + void fill(TT)(TT value) { + cells.fill(value); + } + + void clear() { + cells.clear(); + rowCount = 0; + colCount = 0; + } + + void free() { + cells.free(); + rowCount = 0; + colCount = 0; + } +} + +unittest {} diff --git a/core/fmt.d b/core/fmt.d new file mode 100644 index 0000000..e676da5 --- /dev/null +++ b/core/fmt.d @@ -0,0 +1,78 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.fmt; + +/// The fmt module simplifies value formatting, +/// enabling conversion of data to strings and providing control over output appearance. + +import io = core.stdc.stdio; +import popka.core.strconv; + +const(char)[] fmt(A...)(const(char)[] str, A args) { + static char[1024][4] bufs = void; + static auto bufi = 0; + + bufi = (bufi + 1) % bufs.length; + auto result = bufs[bufi][]; + auto resi = 0; + auto stri = 0; + auto argi = 0; + + while (stri < str.length) { + auto c1 = str[stri]; + auto c2 = stri + 1 >= str.length ? '+' : str[stri + 1]; + if (c1 == '{' && c2 == '}' && argi < args.length) { + static foreach (i, arg; args) { + if (i == argi) { + auto temp = toStr(arg); + result[resi .. resi + temp.length] = temp; + resi += temp.length; + stri += 2; + argi += 1; + goto exitLoopEarly; + } + } + exitLoopEarly: + } else { + result[resi] = c1; + resi += 1; + stri += 1; + } + } + result = result[0 .. resi]; + return result; +} + +void printf(A...)(const(char)[] str, A args) { + io.fputs(fmt("{}\0", fmt(str, args)).ptr, io.stdout); +} + +void printfln(A...)(const(char)[] str, A args) { + io.fputs(fmt("{}\n\0", fmt(str, args)).ptr, io.stdout); +} + +void print(A...)(A args) { + static foreach (arg; args) { + printf("{}", arg); + } +} + +void println(A...)(A args) { + static foreach (arg; args) { + printf("{}", arg); + } + printf("\n"); +} + +unittest { + assert(fmt("") == ""); + assert(fmt("{}") == "{}"); + assert(fmt("{}", "1") == "1"); + assert(fmt("{} {}", "1", "2") == "1 2"); + assert(fmt("{} {} {}", "1", "2", "3") == "1 2 3"); + assert(fmt("{} {} {}", 1, -2, 3.69) == "1 -2 3.69"); + assert(fmt("{}", 420, 320, 220, 120, 20) == "420"); + assert(fmt("", 1, -2, 3.69) == ""); + assert(fmt("({})", fmt("({}, {})", false, true)) == "((false, true))"); +} diff --git a/core/io.d b/core/io.d new file mode 100644 index 0000000..c942dda --- /dev/null +++ b/core/io.d @@ -0,0 +1,50 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.io; + +/// The io module facilitates input and output operations, +/// offering functionalities such as file reading and writing. + +import io = core.stdc.stdio; +import popka.core.container; +import popka.core.strconv; + +List!char readText(const(char)[] path) { + auto f = io.fopen(toStrz(path), "rb"); + if (f == null) { + return List!char(); + } + if (io.fseek(f, 0, io.SEEK_END) != 0) { + io.fclose(f); + return List!char(); + }; + + auto fsize = io.ftell(f); + if (fsize == -1) { + io.fclose(f); + return List!char(); + } + if (io.fseek(f, 0, io.SEEK_SET) != 0) { + io.fclose(f); + return List!char(); + } + + auto result = List!char(fsize); + io.fread(result.items.ptr, fsize, 1, f); + io.fclose(f); + return result; +} + +void writeText(const(char)[] path, List!char content) { + auto f = io.fopen(toStrz(path), "w"); + if (f == null) { + return; + } + content.append('\0'); + io.fputs(content.items.ptr, f); + io.fclose(f); + content.pop(); +} + +unittest {} diff --git a/core/math.d b/core/math.d new file mode 100644 index 0000000..9c363bf --- /dev/null +++ b/core/math.d @@ -0,0 +1,488 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.math; + +/// The math module covers essential mathematical operations, vectors, and shapes like rectangles. + +import math = core.stdc.math; + +enum Flip { + none, x, y, xy, +} + +enum Hook { + topLeft, top, topRight, + left, center, right, + bottomLeft, bottom, bottomRight, +} + +struct Vec2 { + float x = 0.0f; + float y = 0.0f; + + this(float x, float y) { + this.x = x; + this.y = y; + } + + this(float x) { + this(x, x); + } + + this(float[2] xy) { + this(xy[0], xy[1]); + } + + Vec2 opUnary(string op)() { + Vec2 result = void; + result.x = mixin(op ~ "x"); + result.y = mixin(op ~ "y"); + return result; + } + + Vec2 opBinary(string op)(Vec2 rhs) { + Vec2 result = void; + result.x = mixin("x" ~ op ~ "rhs.x"); + result.y = mixin("y" ~ op ~ "rhs.y"); + return result; + } + + void opOpAssign(string op)(Vec2 rhs) { + mixin("x" ~ op ~ "=" ~ "rhs.x;"); + mixin("y" ~ op ~ "=" ~ "rhs.y;"); + } + + Vec2 floor() { + return Vec2(x.floor, y.floor); + } + + float length() { + return sqrt(x * x + y * y); + } + + Vec2 normalize() { + float l = length; + if (l == 0.0f) { + return Vec2(); + } else { + return this / Vec2(l); + } + } + + Vec2 directionTo(Vec2 to) { + return (to - this).normalize(); + } + + Vec2 moveTo(Vec2 to, Vec2 delta) { + Vec2 result; + Vec2 offset = this.directionTo(to) * delta; + if (abs(to.x - x) > abs(offset.x)) { + result.x = x + offset.x; + } else { + result.x = to.x; + } + if (abs(to.y - y) > abs(offset.y)) { + result.y = y + offset.y; + } else { + result.y = to.y; + } + return result; + } + + Vec2 moveTo(Vec2 to, Vec2 delta, float slowdown) { + return Vec2( + .moveTo(x, to.x, delta.x, slowdown), + .moveTo(y, to.y, delta.y, slowdown), + ); + } +} + +struct Vec3 { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + + this(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + this(float x) { + this(x, x, x); + } + + this(float[3] xyz) { + this(xyz[0], xyz[1], xyz[2]); + } + + this(Vec2 xy, float z) { + this(xy.x, xy.y, z); + } + + Vec3 opUnary(string op)() { + Vec3 result = void; + result.x = mixin(op ~ "x"); + result.y = mixin(op ~ "y"); + result.z = mixin(op ~ "z"); + return result; + } + + Vec3 opBinary(string op)(Vec3 rhs) { + Vec3 result = void; + result.x = mixin("x" ~ op ~ "rhs.x"); + result.y = mixin("y" ~ op ~ "rhs.y"); + result.z = mixin("z" ~ op ~ "rhs.z"); + return result; + } + + void opOpAssign(string op)(Vec3 rhs) { + mixin("x" ~ op ~ "=" ~ "rhs.x;"); + mixin("y" ~ op ~ "=" ~ "rhs.y;"); + mixin("z" ~ op ~ "=" ~ "rhs.z;"); + } + + Vec3 floor() { + return Vec3(x.floor, y.floor, z.floor); + } +} + +struct Vec4 { + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + float w = 0.0f; + + this(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + this(float x) { + this(x, x, x, x); + } + + this(float[4] xyzw) { + this(xyzw[0], xyzw[1], xyzw[2], xyzw[3]); + } + + Vec4 opUnary(string op)() { + Vec4 result = void; + result.x = mixin(op ~ "x"); + result.y = mixin(op ~ "y"); + result.z = mixin(op ~ "z"); + result.w = mixin(op ~ "w"); + return result; + } + + Vec4 opBinary(string op)(Vec4 rhs) { + Vec4 result = void; + result.x = mixin("x" ~ op ~ "rhs.x"); + result.y = mixin("y" ~ op ~ "rhs.y"); + result.z = mixin("z" ~ op ~ "rhs.z"); + result.w = mixin("w" ~ op ~ "rhs.w"); + return result; + } + + void opOpAssign(string op)(Vec4 rhs) { + mixin("x" ~ op ~ "=" ~ "rhs.x;"); + mixin("y" ~ op ~ "=" ~ "rhs.y;"); + mixin("z" ~ op ~ "=" ~ "rhs.z;"); + mixin("w" ~ op ~ "=" ~ "rhs.w;"); + } + + Vec4 floor() { + return Vec4(x.floor, y.floor, z.floor, w.floor); + } +} + +struct Rect { + Vec2 position; + Vec2 size; + + this(Vec2 position, Vec2 size) { + this.position = position; + this.size = size; + } + + this(Vec2 size) { + this.size = size; + } + + this(float x, float y, float w, float h) { + this.position.x = x; + this.position.y = y; + this.size.x = w; + this.size.y = h; + } + + this(float w, float h) { + this.size.x = w; + this.size.y = h; + } + + void fix() { + if (size.x < 0.0f) { + position.x = position.x + size.x; + size.x = -size.x; + } + if (size.y < 0.0f) { + position.y = position.y + size.y; + size.y = -size.y; + } + } + + Rect floor() { + Rect result = void; + result.position = position.floor; + result.size = size.floor; + return result; + } + + Vec2 origin(Hook hook) { + final switch (hook) { + case Hook.topLeft: return size * Vec2(0.0f, 0.0f); + case Hook.top: return size * Vec2(0.5f, 0.0f); + case Hook.topRight: return size * Vec2(1.0f, 0.0f); + case Hook.left: return size * Vec2(0.0f, 0.5f); + case Hook.center: return size * Vec2(0.5f, 0.5f); + case Hook.right: return size * Vec2(1.0f, 0.5f); + case Hook.bottomLeft: return size * Vec2(0.0f, 1.0f); + case Hook.bottom: return size * Vec2(0.5f, 1.0f); + case Hook.bottomRight: return size * Vec2(1.0f, 1.0f); + } + } + + Rect rect(Hook hook) { + Rect result = void; + result.position = position - origin(hook); + result.size = size; + return result; + } + + Vec2 point(Hook hook) { + Vec2 result = void; + result = position + origin(hook); + return result; + } + + bool hasPoint(Vec2 point) { + return ( + point.x >= position.x && + point.x <= position.x + size.x && + point.y >= position.y && + point.y <= position.y + size.y + ); + } + + bool hasIntersection(Rect area) { + return ( + position.x + size.x >= area.position.x && + position.x <= area.position.x + area.size.x && + position.y + size.y >= area.position.y && + position.y <= area.position.y + area.size.y + ); + } + + Rect intersection(Rect area) { + Rect result = void; + if (!this.hasIntersection(area)) { + result = Rect(); + } else { + float maxY = max(position.x, area.position.x); + float maxX = max(position.y, area.position.y); + result.position.x = maxX; + result.position.y = maxY; + result.size.x = min(position.x + size.x, area.position.x + area.size.x) - maxX; + result.size.y = min(position.y + size.y, area.position.y + area.size.y) - maxY; + } + return result; + } + + Rect merger(Rect area) { + Rect result = void; + float minX = min(position.x, area.position.x); + float minY = min(position.y, area.position.y); + result.position.x = minX; + result.position.y = minY; + result.size.x = max(position.x + size.x, area.position.x + area.size.x) - minX; + result.size.y = max(position.y + size.y, area.position.y + area.size.y) - minY; + return result; + } + + Rect addLeft(float amount) { + position.x -= amount; + size.x += amount; + return Rect(position.x, position.y, amount, size.y); + } + + Rect addRight(float amount) { + float w = size.x; + size.x += amount; + return Rect(w, position.y, amount, size.y); + } + + Rect addTop(float amount) { + position.y -= amount; + size.y += amount; + return Rect(position.x, position.y, size.x, amount); + } + + Rect addBottom(float amount) { + float h = size.y; + size.y += amount; + return Rect(position.x, h, size.x, amount); + } + + Rect subLeft(float amount) { + float x = position.x; + position.x = min(position.x + amount, position.x + size.x); + size.x = max(size.x - amount, 0.0f); + return Rect(x, position.y, amount, size.y); + } + + Rect subRight(float amount) { + size.x = max(size.x - amount, 0.0f); + return Rect(position.x + size.x, position.y, amount, size.y); + } + + Rect subTop(float amount) { + float y = position.y; + position.y = min(position.y + amount, position.y + size.y); + size.y = max(size.y - amount, 0.0f); + return Rect(position.x, y, size.x, amount); + } + + Rect subBottom(float amount) { + size.y = max(size.y - amount, 0.0f); + return Rect(position.x, position.y + size.y, size.x, amount); + } + + void addLeftRight(float amount) { + this.addLeft(amount); + this.addRight(amount); + } + + void addTopBottom(float amount) { + this.addTop(amount); + this.addBottom(amount); + } + + void addAll(float amount) { + this.addLeftRight(amount); + this.addTopBottom(amount); + } + + void subLeftRight(float amount) { + this.subLeft(amount); + this.subRight(amount); + } + + void subTopBottom(float amount) { + this.subTop(amount); + this.subBottom(amount); + } + + void subAll(float amount) { + this.subLeftRight(amount); + this.subTopBottom(amount); + } + + Rect left(float amount) { + Rect temp = this; + return temp.subLeft(amount); + } + + Rect right(float amount) { + Rect temp = this; + return temp.subRight(amount); + } + + Rect top(float amount) { + Rect temp = this; + return temp.subTop(amount); + } + + Rect bottom(float amount) { + Rect temp = this; + return temp.subBottom(amount); + } +} + +float sqrt(float x) { + return math.sqrtf(x); +} + +float min(float a, float b) { + return a <= b ? a : b; +} + +float max(float a, float b) { + return a <= b ? b : a; +} + +float sign(float x) { + return x <= 0.0f ? -1.0f : 1.0f; +} + +float abs(float x) { + return x <= 0.0f ? -x : x; +} + +float floor(float x) { + float xx = cast(float) cast(int) x; + return (x <= 0.0f && xx != x) ? xx - 1.0f : xx; +} + +float ceil(float x) { + float xx = cast(float) cast(int) x; + return (x <= 0.0f || xx == x) ? xx : xx + 1.0f; +} + +float round(float x) { + return x <= 0.0f ? cast(float) cast(int) (x - 0.5f) : cast(float) cast(int) (x + 0.5f); +} + +float clamp(float x, float a, float b) { + return x <= a ? a : x >= b ? b : x; +} + +float wrap(float x, float a, float b) { + auto result = x; + while (result < a) { + result += b - a; + } + while (result > b) { + result -= b - a; + } + return result; +} + +float lerp(float from, float to, float weight) { + return from + (to - from) * weight; +} + +float smoothstep(float from, float to, float weight) { + float v = weight * weight * (3.0f - 2.0f * weight); + return (to * v) + (from * (1.0f - v)); +} + +float smootherstep(float from, float to, float weight) { + float v = weight * weight * weight * (weight * (weight * 6.0f - 15.0f) + 10.0f); + return (to * v) + (from * (1.0f - v)); +} + +float moveTo(float from, float to, float delta) { + if (abs(to - from) > abs(delta)) return from + sign(to - from) * delta; + else return to; +} + +float moveTo(float from, float to, float delta, float slowdown) { + float target = ((from * (slowdown - 1.0f)) + to) / slowdown; + return from + (target - from) * delta; +} + +unittest {} diff --git a/core/strconv.d b/core/strconv.d new file mode 100644 index 0000000..dae1bbe --- /dev/null +++ b/core/strconv.d @@ -0,0 +1,279 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.strconv; + +/// The strconv module offers procedures for both +/// parsing strings into numeric data types +/// and formatting numbers into string representations. + +struct ToStrOptions { + uint floatPrecision = 2; +} + +struct ToNumResult(T) { + alias Error = ubyte; + enum : Error { + ok, + invalid, + overflow, + } + + T value; + Error error; +} + +const(char)[] boolToStr(bool value) { + static char[64] buf = void; + auto result = buf[]; + + if (value) { + result[0 .. 4] = "true"; + result = result[0 .. 4]; + } else { + result[0 .. 5] = "false"; + result = result[0 .. 5]; + } + return result; +} + +const(char)[] unsignedToStr(ulong value) { + static char[64] buf = void; + auto result = buf[]; + + if (value == 0) { + result[0] = '0'; + result = result[0 .. 1]; + } else { + auto digitCount = 0; + for (auto temp = value; temp != 0; temp /= 10) { + result[$ - 1 - digitCount] = (temp % 10) + '0'; + digitCount += 1; + } + result = result[$ - digitCount .. $]; + } + return result; +} + +const(char)[] signedToStr(long value) { + static char[64] buf = void; + auto result = buf[]; + + if (value < 0) { + auto temp = unsignedToStr(-value); + result[0] = '-'; + result[1 .. 1 + temp.length] = temp; + result = result[0 .. 1 + temp.length]; + } else { + auto temp = unsignedToStr(value); + result[0 .. temp.length] = temp; + result = result[0 .. temp.length]; + } + return result; +} + +const(char)[] floatToStr(double value, uint precision = 2) { + static char[64] buf = void; + auto result = buf[]; + + auto fractionalDigitCount = 0; + auto cleanNumber = value; + while (cleanNumber != cast(double) (cast(long) cleanNumber)) { + fractionalDigitCount += 1; + cleanNumber *= 10; + } + + auto temp = signedToStr(cast(long) cleanNumber); + auto i = result.length; + + if (temp.length <= fractionalDigitCount) { + i -= temp.length; + result[i .. i + temp.length] = temp; + if (temp.length < fractionalDigitCount) { + i -= fractionalDigitCount - temp.length; + result[i .. i + fractionalDigitCount - temp.length] = '0'; + } + i -= 2; + result[i .. i + 2] = "0."; + } else { + if (fractionalDigitCount == 0) { + i -= (precision == 0 ? 1 : precision); + result[i .. i + (precision == 0 ? 1 : precision)] = '0'; + i -= 1; + result[i] = '.'; + i -= temp.length; + result[i .. i + temp.length] = temp; + } else { + i -= fractionalDigitCount; + result[i .. i + fractionalDigitCount] = temp[$ - fractionalDigitCount .. $]; + i -= 1; + result[i] = '.'; + i -= (temp.length - fractionalDigitCount); + result[i .. i + (temp.length - fractionalDigitCount)] = temp[0 .. $ - fractionalDigitCount]; + } + } + + if (precision == 0) { + result = result[i .. $]; + } else { + result = result[i .. $ - fractionalDigitCount + (precision > fractionalDigitCount ? fractionalDigitCount : precision)]; + } + return result; +} + +const(char)[] charToStr(char value) { + static char[1] buf = void; + auto result = buf[]; + + result[0] = value; + result = result[0 .. 1]; + return result; +} + +const(char)[] strzToStr(const(char)* value) { + static char[1024] buf = void; + auto result = buf[]; + + size_t strzLength = 0; + while (value[strzLength] != '\0') { + strzLength += 1; + } + result[0 .. strzLength] = value[0 .. strzLength]; + result = result[0 .. strzLength]; + return result; +} + +const(char)[] strToStr(const(char)[] value) { + static char[1024] buf = void; + auto result = buf[]; + + result[0 .. value.length] = value; + result = result[0 .. value.length]; + return result; +} + +const(char)[] toStr(T)(T value, ToStrOptions opt = ToStrOptions()) { + enum isBool = is(T == bool); + enum isUnsigned = is(T == ubyte) || is(T == ushort) || is(T == uint) || is(T == ulong); + enum isSigned = is(T == byte) || is(T == short) || is(T == int) || is(T == long); + enum isFloat = is(T == float) || is(T == double); + enum isChar = is(T == char) || is(T == const(char)) || is(T == immutable(char)); + enum isStrz = is(T : const(char)*); + enum isStr = is(T : const(char)[]); + + static if (isBool) { + return boolToStr(value); + } else static if (isUnsigned) { + return unsignedToStr(value); + } else static if (isSigned) { + return signedToStr(value); + } else static if (isFloat) { + return floatToStr(value, opt.floatPrecision); + } else static if (isChar) { + return charToStr(value); + } else static if (isStrz) { + return strzToStr(value); + } else static if (isStr) { + return strToStr(value); + } else { + static assert(0, "The 'toStr' function exclusively handles numerical valueues, booleans, characters and strings."); + } +} + +ToNumResult!bool toBool(const(char)[] str) { + auto result = ToNumResult!bool(); + if (str == "true") { + result.value = true; + } else if (str == "false") { + result.value = false; + } else { + result.error = result.invalid; + } + return result; +} + +ToNumResult!ulong toUnsigned(const(char)[] str) { + auto result = ToNumResult!ulong(); + + if (str.length == 0) { + result.error = result.invalid; + } else if (str.length >= 18) { + result.error = result.overflow; + } else { + ulong level = 1; + foreach_reverse (i, c; str) { + if (c < '0' || c > '9') { + result.error = result.invalid; + break; + } + auto digit = c - '0'; + result.value += digit * level; + level *= 10; + } + } + return result; +} + +ToNumResult!long toSigned(const(char)[] str) { + auto result = ToNumResult!long(); + + if (str.length == 0) { + result.error = result.invalid; + } else if (str.length >= 18) { + result.error = result.overflow; + } else { + if (str[0] == '-') { + auto conv = toUnsigned(str[1 .. $]); + if (conv.error) { + result.error = conv.error; + } else { + result.value = -conv.value; + } + } else { + auto conv = toUnsigned(str); + if (conv.error) { + result.error = conv.error; + } else { + result.value = conv.value; + } + } + } + return result; +} + +ToNumResult!double toFloat(const(char)[] str) { + auto result = ToNumResult!double(); + + foreach (i, c; str) { + if (c == '.') { + auto lhs = toSigned(str[0 .. i]); + if (lhs.error) { + result.error = lhs.error; + } else { + auto rhs = toSigned(str[i + 1 .. $]); + if (rhs.error) { + result.error = rhs.error; + } else { + auto rhsLevel = 10; + foreach (_; 1 .. str[i + 1 .. $].length) { + rhsLevel *= 10; + } + result.value = lhs.value + ((lhs.value < 0 ? -1 : 1) * rhs.value / cast(double) rhsLevel); + } + } + break; + } + } + return result; +} + +const(char)* toStrz(const(char)[] str) { + static char[1024] buf = void; + auto result = buf[]; + + result[0 .. str.length] = str; + result[str.length] = '\0'; + return result.ptr; +} + +unittest {} diff --git a/core/strutils.d b/core/strutils.d new file mode 100644 index 0000000..4e12ed1 --- /dev/null +++ b/core/strutils.d @@ -0,0 +1,149 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.strutils; + +/// The strutils module contains handy procedures designed to assist with various string manipulation tasks. + +import popka.core.ascii; + +bool isStrz(const(char)[] str) { + return str.length != 0 && str[$ - 1] == '\0'; +} + +bool equals(const(char)[] str, const(char)[] other) { + return str == other; +} + +bool equalsi(const(char)[] str, const(char)[] other) { + if (str.length != other.length) return false; + foreach (i; 0 .. str.length) { + if (toUpper(str[i]) != toUpper(other[i])) return false; + } + return true; +} + +bool startsWith(const(char)[] str, const(char)[] start) { + if (str.length < start.length) return false; + return str[0 .. start.length] == start; +} + +bool startsWithi(const(char)[] str, const(char)[] start) { + if (str.length < start.length) return false; + foreach (i; 0 .. start.length) { + if (toUpper(str[i]) != toUpper(start[i])) return false; + } + return true; +} + +bool endsWith(const(char)[] str, const(char)[] end) { + if (str.length < end.length) return false; + return str[$ - end.length - 1 .. end.length] == end; +} + +bool endsWithi(const(char)[] str, const(char)[] end) { + if (str.length < end.length) return false; + foreach (i; str.length - end.length - 1 .. end.length) { + if (toUpper(str[i]) != toUpper(end[i])) return false; + } + return true; +} + +int count(const(char)[] str, const(char)[] item) { + int result = 0; + if (str.length < item.length || item.length == 0) return result; + foreach (i; 0 .. str.length - item.length) { + if (str[i .. i + item.length] == item) { + result += 1; + i += item.length - 1; + } + } + return result; +} + +int counti(const(char)[] str, const(char)[] item) { + int result = 0; + if (str.length < item.length || item.length == 0) return result; + foreach (i; 0 .. str.length - item.length) { + if (equalsi(str[i .. i + item.length], item)) { + result += 1; + i += item.length - 1; + } + } + return result; +} + +int findStart(const(char)[] str, const(char)[] item) { + if (str.length < item.length || item.length == 0) return -1; + foreach (i; 0 .. str.length - item.length) { + if (str[i + item.length .. item.length] == item) return cast(int) i; + } + return -1; +} + +int findStarti(const(char)[] str, const(char)[] item) { + if (str.length < item.length || item.length == 0) return -1; + foreach (i; 0 .. str.length - item.length) { + if (equalsi(str[i + item.length .. item.length], item)) return cast(int) i; + } + return -1; +} + +int findEnd(const(char)[] str, const(char)[] item) { + if (str.length < item.length || item.length == 0) return -1; + foreach_reverse (i; 0 .. str.length - item.length) { + if (str[i + item.length .. item.length] == item) return cast(int) i; + } + return -1; +} + +int findEndi(const(char)[] str, const(char)[] item) { + if (str.length < item.length || item.length == 0) return -1; + foreach_reverse (i; 0 .. str.length - item.length) { + if (equalsi(str[i + item.length .. item.length], item)) return cast(int) i; + } + return -1; +} + +const(char)[] trimStart(const(char)[] str) { + const(char)[] result = str; + while (result.length > 0) { + if (isSpace(result[0])) result = result[1 .. $]; + else break; + } + return result; +} + +const(char)[] trimEnd(const(char)[] str) { + const(char)[] result = str; + while (result.length > 0) { + if (isSpace(result[$ - 1])) result = result[0 .. $ - 1]; + else break; + } + return result; +} + +const(char)[] trim(const(char)[] str) { + return str.trimStart().trimEnd(); +} + +const(char)[] skipValue(ref const(char)[] str, char sep = ',') { + foreach (i; 0 .. str.length) { + if (str[i] == sep) { + auto line = str[0 .. i]; + str = str[i + 1 .. $]; + return line; + } else if (i == str.length - 1) { + auto line = str[0 .. i + 1]; + str = str[i + 1 .. $]; + return line; + } + } + return ""; +} + +const(char)[] skipLine(ref const(char)[] str) { + return skipValue(str, '\n'); +} + +unittest {} diff --git a/core/sumtype.d b/core/sumtype.d new file mode 100644 index 0000000..baf012d --- /dev/null +++ b/core/sumtype.d @@ -0,0 +1,82 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.core.sumtype; + +/// The sumtype module defines a data structure that can hold one of several possible types. +/// It provides functionalities to construct, access, and manipulate these values. + +struct None {}; + +struct SumType(A...) { + template memberName(T) { + mixin("enum memberName = \"" ~ ((T.stringof[0] >= 'A' && T.stringof[0] <= 'Z') ? cast(char) (T.stringof[0] + 32) : T.stringof[0]) ~ T.stringof[1 .. $] ~ "\";"); + } + + template dataName(T) { + mixin("enum dataName = \"" ~ memberName!T ~ "Data\";"); + } + + template kindName(T) { + mixin("enum kindName = \"" ~ memberName!T ~ "Kind\";"); + } + + union Data { + static foreach (T; A) { + mixin("T ", dataName!T, ";"); + } + } + + alias Kind = ushort; + static foreach (i, T; A) { + mixin("enum ", kindName!T, " = ", i, ";"); + } + + Data data; + Kind kind; + alias this = data; + + static foreach (i, T; A) { + this(T data) { + this.data = *(cast(Data*) &data); + this.kind = i; + } + } + + static foreach (i, T; A) { + void opAssign(T rhs) { + data = *(cast(Data*) &rhs); + kind = i; + } + } + + auto call(string f, AA...)(AA args) { + final switch (kind) { + static foreach (T; A) { + mixin("case ", kindName!T, ": return ", dataName!T, ".", f ~ "(args);"); + } + } + } +} + +alias Optional(T) = SumType!(None, T); + +bool hasCommonBase(T)() { + alias Base = typeof(T.init.data.tupleof[0]); + + static foreach (member; T.init.data.tupleof[1 .. $]) { + static if (member.tupleof.length == 0) { + return false; + } else static if (!is(Base == typeof(member.tupleof[0]))) { + return false; + } + } + return true; +} + +mixin template AddBase(T) { + T base; + alias this = base; +} + +unittest {} diff --git a/dub.json b/dub.json new file mode 100644 index 0000000..3fe0e38 --- /dev/null +++ b/dub.json @@ -0,0 +1,10 @@ +{ + "authors": [ + "Alexandros F. G. Kapretsos" + ], + "copyright": "Copyright © 2024, Alexandros F. G. Kapretsos", + "description": "A lightweight and beginner-friendly 2D game engine for the D programming language.", + "license": "MIT", + "name": "popka", + "sourcePaths": ["."] +} diff --git a/game/basic.d b/game/basic.d new file mode 100644 index 0000000..99c6d22 --- /dev/null +++ b/game/basic.d @@ -0,0 +1,13 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.game.basic; + +/// The basic module acts as a central hub, +/// bundling together numerous specialized modules +/// to provide an extensive array of tools catering to a variety of programming tasks. + +public import popka.game.dialogue; +public import popka.game.engine; + +unittest {} diff --git a/game/dialogue.d b/game/dialogue.d new file mode 100644 index 0000000..182c25b --- /dev/null +++ b/game/dialogue.d @@ -0,0 +1,86 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.game.dialogue; + +/// The dialogue module is a versatile dialogue system for games, +/// enabling the creation of interactive conversations and branching narratives. + +import popka.core.basic; + +struct DialogueUnit { + alias Kind = char; + enum : Kind { + pause = '-', + comment = '#', + point = '*', + target = '@', + actor = '>', + line = '|', + } + + List!char content; + Kind kind = pause; + + bool isOneOf(const(Kind)[] args...) { + foreach (arg; args) { + if (arg == kind) { + return true; + } + } + return false; + } +} + +struct Dialogue { + List!DialogueUnit units; + size_t index; + + this(const(char)[] path) { + read(path); + } + + DialogueUnit* now() { + return &units[index]; + } + + void update() { + if (units.length != 0 && index < units.length - 1) { + index += 1; + } + } + + void free() { + foreach (ref unit; units.items) { + unit.content.free(); + } + units.free(); + } + + void read(const(char)[] path) { + free(); + units.append(DialogueUnit(List!char(), DialogueUnit.pause)); + + auto file = readText(path); + const(char)[] view = file.items; + auto lineNumber = 0; + while (view.length != 0) { + auto line = skipLine(view); + if (line.length == 0) { + continue; + } + lineNumber += 1; + if (lineNumber == 1 && line[0] == DialogueUnit.pause) { + continue; + } + + units.append(DialogueUnit(List!char(trimStart(line[1 .. $])), line[0])); + } + if (units.items[$ - 1].kind != DialogueUnit.pause) { + units.append(DialogueUnit(List!char(), DialogueUnit.pause)); + } + file.free(); + } +} + +unittest {} diff --git a/game/engine.d b/game/engine.d new file mode 100644 index 0000000..c826d0c --- /dev/null +++ b/game/engine.d @@ -0,0 +1,838 @@ +// Copyright 2024 Alexandros F. G. Kapretsos +// SPDX-License-Identifier: MIT + +module popka.game.engine; + +/// The engine module functions as a lightweight 2D game engine, +/// designed to provide essential tools and functionalities for developing games with ease and efficiency. + +import ray = popka.vendor.ray.raylib; +import popka.core.basic; + +bool popkaState; +Color popkaBackgroundColor = gray; + +View popkaView; +float popkaViewWidth = 320.0f; +float popkaViewHeight = 180.0f; +bool popkaViewLockFlag; +bool popkaViewUnlockFlag; + +bool popkaFullscreenFlag; +Vec2 popkaFullscreenLastWindowSize; +float popkaFullscreenTime = 0.0f; +enum popkaFullscreenWaitTime = 0.175f; + +struct Sprite { + ray.Texture2D data; + + this(const(char)[] path) { + load(path); + } + + bool isEmpty() { + return data.id == 0; + } + + float width() { + return data.width; + } + + float height() { + return data.height; + } + + Vec2 size() { + return Vec2(width, height); + } + + Rect rect() { + return Rect(size); + } + + void load(const(char)[] path) { + free(); + data = ray.LoadTexture(toStrz(path)); + } + + void free() { + if (!isEmpty) { + ray.UnloadTexture(data); + data = ray.Texture2D(); + } + } +} + +struct Font { + ray.Font data; + + this(const(char)[] path, uint size) { + load(path, size); + } + + bool isEmpty() { + return data.texture.id == 0; + } + + float size() { + return data.baseSize; + } + + void load(const(char)[] path, uint size) { + free(); + data = ray.LoadFontEx(toStrz(path), size, null, 0); + } + + void free() { + if (data.texture.id != 0) { + ray.UnloadFont(data); + data = ray.Font(); + } + } +} + +struct View { + ray.RenderTexture2D data; + + this(float width, float height) { + load(width, height); + } + + bool isEmpty() { + return data.texture.id == 0; + } + + float width() { + return data.texture.width; + } + + float height() { + return data.texture.height; + } + + Vec2 size() { + return Vec2(width, height); + } + + Rect rect() { + return Rect(size); + } + + void load(float width, float height) { + free(); + data = ray.LoadRenderTexture(cast(int) width, cast(int) height); + } + + void free() { + if (!isEmpty) { + ray.UnloadRenderTexture(data); + data = ray.RenderTexture(); + } + } +} + +struct TileMap { + Grid!short data; + alias this = data; + + Vec2 cellSize() { + return Vec2(cellWidth, cellHeight); + } + + void cellSize(Vec2 value) { + cellWidth = value.x; + cellHeight = value.y; + } + + Vec2 size() { + return Vec2(width, height); + } + + void load(const(char)[] path) { + free(); + + auto file = readText(path); + const(char)[] view = file.items; + while (view.length != 0) { + auto line = view.skipLine(); + rowCount += 1; + colCount = 0; + while (line.length != 0) { + auto value = line.skipValue(); + colCount += 1; + } + } + resize(rowCount, colCount); + + view = file.items; + foreach (row; 0 .. rowCount) { + auto line = view.skipLine(); + foreach (col; 0 .. colCount) { + auto value = line.skipValue(); + auto conv = value.toSigned(); + if (conv.error) { + data[row, col] = cast(short) -1; + } else { + data[row, col] = cast(short) conv.value; + } + } + } + file.free(); + } +} + +struct Camera { + Vec2 position; + float rotation = 0.0f; + float scale = 1.0f; + Hook hook; + bool isAttached; + + this(Vec2 position) { + this.position = position; + } + + float width() { + return resolution.x * scale; + } + + float height() { + return resolution.y * scale; + } + + Vec2 size() { + return Vec2(width, height); + } + + Vec2 origin() { + return Rect(size).origin(hook); + } + + Rect rect() { + return Rect(position - origin, size); + } + + Vec2 point(Hook hook) { + return rect.point(hook); + } + + void attach() { + if (!isAttached) { + isAttached = true; + auto temp = this.toRay(); + temp.target.x = floor(temp.target.x); + temp.target.y = floor(temp.target.y); + temp.offset.x = floor(temp.offset.x); + temp.offset.y = floor(temp.offset.y); + ray.BeginMode2D(temp); + } + } + + void detach() { + if (isAttached) { + isAttached = false; + ray.EndMode2D(); + } + } + + void follow(Vec2 target, float slowdown = 0.14f) { + if (slowdown <= 0.0f) { + position = target; + } else { + position = position.moveTo(target, Vec2(deltaTime), slowdown); + } + } +} + +enum Keyboard { + a = ray.KEY_A, + b = ray.KEY_B, + c = ray.KEY_C, + d = ray.KEY_D, + e = ray.KEY_E, + f = ray.KEY_F, + g = ray.KEY_G, + h = ray.KEY_H, + i = ray.KEY_I, + j = ray.KEY_J, + k = ray.KEY_K, + l = ray.KEY_L, + m = ray.KEY_M, + n = ray.KEY_N, + o = ray.KEY_O, + p = ray.KEY_P, + q = ray.KEY_Q, + r = ray.KEY_R, + s = ray.KEY_S, + t = ray.KEY_T, + u = ray.KEY_U, + v = ray.KEY_V, + w = ray.KEY_W, + x = ray.KEY_X, + y = ray.KEY_Y, + z = ray.KEY_Z, + n0 = ray.KEY_ZERO, + n1 = ray.KEY_ONE, + n2 = ray.KEY_TWO, + n3 = ray.KEY_THREE, + n4 = ray.KEY_FOUR, + n5 = ray.KEY_FIVE, + n6 = ray.KEY_SIX, + n7 = ray.KEY_SEVEN, + n8 = ray.KEY_EIGHT, + n9 = ray.KEY_NINE, + f1 = ray.KEY_F1, + f2 = ray.KEY_F2, + f3 = ray.KEY_F3, + f4 = ray.KEY_F4, + f5 = ray.KEY_F5, + f6 = ray.KEY_F6, + f7 = ray.KEY_F7, + f8 = ray.KEY_F8, + f9 = ray.KEY_F9, + f10 = ray.KEY_F10, + f11 = ray.KEY_F11, + f12 = ray.KEY_F12, + left = ray.KEY_LEFT, + right = ray.KEY_RIGHT, + up = ray.KEY_UP, + down = ray.KEY_DOWN, + esc = ray.KEY_ESCAPE, + enter = ray.KEY_ENTER, + tab = ray.KEY_TAB, + space = ray.KEY_SPACE, + backspace = ray.KEY_BACKSPACE, + shift = ray.KEY_LEFT_SHIFT, + ctrl = ray.KEY_LEFT_CONTROL, + alt = ray.KEY_LEFT_ALT, + win = ray.KEY_LEFT_SUPER, +} + +enum Mouse { + left = ray.MOUSE_BUTTON_LEFT, + right = ray.MOUSE_BUTTON_RIGHT, + middle = ray.MOUSE_BUTTON_MIDDLE, +} + +enum Gamepad { + left = ray.GAMEPAD_BUTTON_LEFT_FACE_LEFT, + right = ray.GAMEPAD_BUTTON_LEFT_FACE_RIGHT, + up = ray.GAMEPAD_BUTTON_LEFT_FACE_UP, + down = ray.GAMEPAD_BUTTON_LEFT_FACE_DOWN, + y = ray.GAMEPAD_BUTTON_RIGHT_FACE_UP, + x = ray.GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, + a = ray.GAMEPAD_BUTTON_RIGHT_FACE_DOWN, + b = ray.GAMEPAD_BUTTON_RIGHT_FACE_LEFT, + lb = ray.GAMEPAD_BUTTON_LEFT_TRIGGER_1, + lt = ray.GAMEPAD_BUTTON_LEFT_TRIGGER_2, + lsb = ray.GAMEPAD_BUTTON_LEFT_THUMB, + rb = ray.GAMEPAD_BUTTON_RIGHT_TRIGGER_1, + rt = ray.GAMEPAD_BUTTON_RIGHT_TRIGGER_2, + rsb = ray.GAMEPAD_BUTTON_RIGHT_THUMB, + back = ray.GAMEPAD_BUTTON_MIDDLE_LEFT, + start = ray.GAMEPAD_BUTTON_MIDDLE_RIGHT, + center = ray.GAMEPAD_BUTTON_MIDDLE, +} + +// # Converters + +Color toPopka(ray.Color from) { + return Color(from.r, from.g, from.b, from.a); +} + +Vec2 toPopka(ray.Vector2 from) { + return Vec2(from.x, from.y); +} + +Vec3 toPopka(ray.Vector3 from) { + return Vec3(from.x, from.y, from.z); +} + +Vec4 toPopka(ray.Vector4 from) { + return Vec4(from.x, from.y, from.z, from.w); +} + +Rect toPopka(ray.Rectangle from) { + return Rect(from.x, from.y, from.width, from.height); +} + +Sprite toPopka(ray.Texture2D from) { + Sprite result; + result.data = from; + return result; +} + +Font toPopka(ray.Font from) { + Font result; + result.data = from; + return result; +} + +View toPopka(ray.RenderTexture2D from) { + View result; + result.data = from; + return result; +} + +Camera toPopka(ray.Camera2D from) { + Camera result; + result.position = from.target.toPopka(); + result.rotation = from.rotation; + result.scale = from.zoom; + return result; +} + +ray.Color toRay(Color from) { + return ray.Color(from.r, from.g, from.b, from.a); +} + +ray.Vector2 toRay(Vec2 from) { + return ray.Vector2(from.x, from.y); +} + +ray.Vector3 toRay(Vec3 from) { + return ray.Vector3(from.x, from.y, from.z); +} + +ray.Vector4 toRay(Vec4 from) { + return ray.Vector4(from.x, from.y, from.z, from.w); +} + +ray.Rectangle toRay(Rect from) { + return ray.Rectangle(from.position.x, from.position.y, from.size.x, from.size.y); +} + +ray.Texture2D toRay(Sprite from) { + return from.data; +} + +ray.Font toRay(Font from) { + return from.data; +} + +ray.RenderTexture2D toRay(View from) { + return from.data; +} + +ray.Camera2D toRay(Camera from) { + return ray.Camera2D(from.origin.toRay(), from.position.toRay(), from.rotation, from.scale); +} + +void gprintf(size_t line = __LINE__, A...)(const(char)[] str, A args) { + static auto timer = 0.0f; + enum waitTime = 0.5f; + + timer += deltaTime; + if (timer > waitTime) { + timer -= waitTime; + printf(str, args); + } +} + +void gprintfln(size_t line = __LINE__, A...)(const(char)[] str, A args) { + static auto timer = 0.0f; + enum waitTime = 0.5f; + + timer += deltaTime; + if (timer > waitTime) { + timer -= waitTime; + printfln(str, args); + } +} + +void gprint(size_t line = __LINE__, A...)(A args) { + static auto timer = 0.0f; + enum waitTime = 0.5f; + + timer += deltaTime; + if (timer > waitTime) { + timer -= waitTime; + print(args); + } +} + +void gprintln(size_t line = __LINE__, A...)(A args) { + static auto timer = 0.0f; + enum waitTime = 0.5f; + + timer += deltaTime; + if (timer > waitTime) { + timer -= waitTime; + println(args); + } +} + +int randi() { + return ray.GetRandomValue(0, int.max); +} + +float randf() { + return ray.GetRandomValue(0, cast(int) float.max) / cast(float) cast(int) float.max; +} + +void randomize(uint seed) { + ray.SetRandomSeed(seed); +} + +void randomize() { + randomize(randi); +} + +void openWindow(float width, float height, const(char)[] title = "Popka", Color backgroundColor = gray) { + ray.SetConfigFlags(ray.FLAG_VSYNC_HINT | ray.FLAG_WINDOW_RESIZABLE); + ray.SetTraceLogLevel(ray.LOG_ERROR); + ray.InitWindow(cast(int) width, cast(int) height, toStrz(title)); + ray.SetWindowMinSize(cast(int) (width * 0.2f), cast(int) (height * 0.2f)); + ray.SetExitKey(ray.KEY_NULL); + ray.SetTargetFPS(60); + popkaState = true; + popkaFullscreenLastWindowSize = Vec2(width, height); + popkaBackgroundColor = backgroundColor; +} + +void closeWindow() { + popkaState = false; +} + +void freeWindow() { + ray.CloseWindow(); +} + +bool isWindowOpen() { + static auto isFirstCall = true; + + auto result = !(ray.WindowShouldClose() || !popkaState); + if (result) { + if (isFirstCall) { + // Begin drawing. + if (isResolutionLocked) { + ray.BeginTextureMode(popkaView.data); + } else { + ray.BeginDrawing(); + } + ray.ClearBackground(popkaBackgroundColor.toRay()); + isFirstCall = false; + } else { + // End drawing. + if (isResolutionLocked) { + auto minSize = popkaView.size; + auto maxSize = windowSize; + auto ratio = maxSize / minSize; + auto minRatio = min(ratio.x, ratio.y); + auto targetSize = minSize * Vec2(minRatio); + auto targetPos = maxSize * Vec2(0.5f) - targetSize * Vec2(0.5f); + ray.EndTextureMode(); + ray.BeginDrawing(); + ray.ClearBackground(ray.BLACK); + ray.DrawTexturePro( + popkaView.data.texture, + ray.Rectangle(0.0f, 0.0f, minSize.x, -minSize.y), + ray.Rectangle( + ratio.x == minRatio ? targetPos.x : targetPos.x.floor, + ratio.y == minRatio ? targetPos.y : targetPos.y.floor, + ratio.x == minRatio ? targetSize.x : targetSize.x.floor, + ratio.y == minRatio ? targetSize.y : targetSize.y.floor, + ), + ray.Vector2(0.0f, 0.0f), + 0.0f, + ray.WHITE, + ); + ray.EndDrawing(); + } else { + ray.EndDrawing(); + } + // Check if the resolution was locked or unlocked. + if (popkaViewLockFlag) { + popkaView.load(popkaViewWidth, popkaViewHeight); + popkaViewLockFlag = false; + } + if (popkaViewUnlockFlag) { + popkaView.free(); + popkaViewUnlockFlag = false; + } + // Begin drawing. + if (isResolutionLocked) { + ray.BeginTextureMode(popkaView.data); + } else { + ray.BeginDrawing(); + } + ray.ClearBackground(popkaBackgroundColor.toRay()); + // Fullscreen code to fix a bug on KDE. + if (popkaFullscreenFlag) { + popkaFullscreenTime += deltaTime; + if (popkaFullscreenTime >= popkaFullscreenWaitTime) { + popkaFullscreenTime = 0.0f; + popkaFullscreenFlag = false; + ray.ToggleFullscreen(); + if (!isFullscreen) { + windowSize(popkaFullscreenLastWindowSize); + } + } + } + } + } + return result; +} + +void lockFPS(uint target) { + ray.SetTargetFPS(target); +} + +void unlockFPS() { + ray.SetTargetFPS(0); +} + +bool isResolutionLocked() { + return !popkaView.isEmpty; +} + +void lockResolution(float width, float height) { + popkaViewWidth = width; + popkaViewHeight = height; + popkaViewLockFlag = true; +} + +void unlockResolution() { + popkaViewUnlockFlag = true; +} + +bool isFullscreen() { + return ray.IsWindowFullscreen; +} + +void toggleFullscreen() { + if (!popkaFullscreenFlag) { + popkaFullscreenFlag = true; + if (!isFullscreen) { + popkaFullscreenLastWindowSize = windowSize; + windowSize(screenSize); + } + } +} + +Vec2 screenSize(uint id) { + return Vec2(ray.GetMonitorWidth(id), ray.GetMonitorHeight(id)); +} + +Vec2 screenSize() { + return screenSize(ray.GetCurrentMonitor()); +} + +Vec2 windowSize() { + if (isFullscreen) { + return screenSize; + } else { + return Vec2(ray.GetScreenWidth(), ray.GetScreenHeight()); + } +} + +void windowSize(Vec2 size) { + auto screen = screenSize; + ray.SetWindowSize(cast(int) size.x, cast(int) size.y); + ray.SetWindowPosition(cast(int) (screen.x * 0.5f - size.x * 0.5f), cast(int) (screen.y * 0.5f - size.y * 0.5f)); +} + +Vec2 resolution() { + if (isResolutionLocked) { + return popkaView.size; + } else { + return windowSize; + } +} + +int fps() { + return ray.GetFPS(); +} + +float deltaTime() { + return ray.GetFrameTime(); +} + +bool isPressed(Keyboard key) { + return ray.IsKeyPressed(key); +} + +bool isPressed(Mouse key) { + return ray.IsMouseButtonPressed(key); +} + +bool isPressed(Gamepad key, uint id = 0) { + return ray.IsGamepadButtonPressed(id, key); +} + +bool isDown(Keyboard key) { + return ray.IsKeyDown(key); +} + +bool isDown(Mouse key) { + return ray.IsMouseButtonDown(key); +} + +bool isDown(Gamepad key, uint id = 0) { + return ray.IsGamepadButtonDown(id, key); +} + +bool isReleased(Keyboard key) { + return ray.IsKeyReleased(key); +} + +bool isReleased(Mouse key) { + return ray.IsMouseButtonReleased(key); +} + +bool isReleased(Gamepad key, uint id = 0) { + return ray.IsGamepadButtonReleased(id, key); +} + +void drawRect(Rect rect, Color color = white) { + ray.DrawRectanglePro(rect.floor.toRay(), ray.Vector2(0.0f, 0.0f), 0.0f, color.toRay()); +} + +void drawSprite(Sprite sprite, Rect region, Vec2 position = Vec2(), float rotation = 0.0f, Vec2 scale = Vec2(1.0f), Color color = white, Flip flip = Flip.none, Hook hook = Hook.topLeft) { + if (sprite.isEmpty) return; + Rect target = Rect(position, region.size * scale); + Rect source = region; + if (region.size.x <= 0.0f || region.size.y <= 0.0f) { + target = Rect(position, sprite.size * scale); + source = Rect(sprite.size); + } else { + target = Rect(position, region.size * scale); + source = region; + } + final switch (flip) { + case Flip.none: break; + case Flip.x: source.size.x *= -1.0f; break; + case Flip.y: source.size.y *= -1.0f; break; + case Flip.xy: source.size *= Vec2(-1.0f); break; + } + ray.DrawTexturePro( + sprite.data, + source.floor().toRay(), + target.floor().toRay(), + target.origin(hook).floor().toRay(), + rotation, + color.toRay(), + ); +} + +void drawTile(Sprite sprite, uint tileID, Vec2 cellSize, Vec2 position = Vec2(), float rotation = 0.0f, Vec2 scale = Vec2(1.0f), Color color = white, Flip flip = Flip.none, Hook hook = Hook.topLeft) { + uint gridWidth = cast(uint) (sprite.width / cellSize.x).floor(); + uint gridHeight = cast(uint) (sprite.height / cellSize.y).floor(); + drawSprite( + sprite, + Rect((tileID % gridWidth) * cellSize.x, (tileID / gridHeight) * cellSize.y, cellSize.x, cellSize.y), + position, + rotation, + scale, + color, + flip, + hook, + ); +} + +void drawTileMap(Sprite sprite, TileMap map, Camera camera = Camera(), Vec2 position = Vec2(), float rotation = 0.0f, Vec2 scale = Vec2(1.0f), Color color = white, Flip flip = Flip.none, Hook hook = Hook.topLeft) { + size_t col1, col2, row1, row2; + if (camera.isAttached) { + col1 = cast(size_t) clamp((camera.point(Hook.topLeft).x - position.x) / map.cellWidth - 4.0f, 0, map.colCount).floor(); + col2 = cast(size_t) clamp((camera.point(Hook.bottomRight).x - position.x) / map.cellWidth + 4.0f, 0, map.colCount).floor(); + row1 = cast(size_t) clamp((camera.point(Hook.topLeft).y - position.y) / map.cellHeight - 4.0f, 0, map.rowCount).floor(); + row2 = cast(size_t) clamp((camera.point(Hook.bottomRight).y - position.y) / map.cellHeight + 4.0f, 0, map.rowCount).floor(); + } else { + col1 = 0; + col2 = map.colCount; + row1 = 0; + row2 = map.rowCount; + } + foreach (row; row1 .. row2) { + foreach (col; col1 .. col2) { + if (map[row, col] == -1) { + continue; + } + drawTile( + sprite, + map[row, col], + map.cellSize, + Vec2(position.x + col * map.cellSize.x, position.y + row * map.cellSize.y), + rotation, + scale, + color, + flip, + hook, + ); + } + } +} + +Font raylibFont() { + return toPopka(ray.GetFontDefault()); +} + +// ----------------- + +// TODO: Text drawing and measuring need rethinking. Do it later... + +// NOTE: drawing sprites, text, tiles. +// NOTE: drawign text will be the raylib func copy-pasted but will take popka font. This will also let us remove the global spacing. +// NOTE: Maybe we can measure the text without using the raylib function??? +Vec2 measureText(const(char)[] text, Font font, float size, Vec2 spacing) { + static char[1024] buf = void; + + const(char)[] strz; + if (text.isStrz) { + strz = text; + } else { + buf[0 .. text.length] = text; + buf[text.length] = '\0'; + strz = buf[0 .. text.length]; + } + + bool hasNewLineChar; + foreach (c; strz) { + if (c == '\n') { + hasNewLineChar = true; + break; + } + } + + ray.SetTextLineSpacing(cast(int) spacing.y); + Vec2 trueSize = ray.MeasureTextEx(font.data, &strz[0], size, spacing.x).toPopka(); + return Vec2(trueSize.x, trueSize.y - (hasNewLineChar ? spacing.y : 0.0f)); +} + +Vec2 measureText(const(char)[] text) { + return measureText(text, raylibFont, 10.0f, Vec2(1.0f, 12.0f)); +} + +// TODO: Needs thinking of how text drawing works. +void drawText(const(char)[] text, Font font, float size, Vec2 spacing, Vec2 positionition, Vec2 origin, float rotation, Color color) { + static char[1024] buf = void; + + const(char)[] strz; + if (text.isStrz) { + strz = text; + } else { + buf[0 .. text.length] = text; + buf[text.length] = '\0'; + strz = buf[0 .. text.length]; + } + + ray.SetTextLineSpacing(cast(int) spacing.y); + ray.DrawTextPro(font.data, &strz[0], positionition.toRay(), origin.toRay(), rotation, size, spacing.x, color.toRay()); +} + +// TODO: Needs thinking of how drawing works. +void drawText(const(char)[] text, Vec2 positionition, Color color) { + drawText(text, raylibFont, 10.0f, Vec2(1.0f, 12.0f), positionition, Vec2(), 0.0f, color); +} + +// TODO: Needs thinking of how drawing works. +void drawText(const(char)[] text) { + drawText(text, Vec2(8.0f), white); +} + +// TODO: Needs thinking of how drawing works. +void drawFPS(float x, float y) { + drawText("FPS: {}".fmt(fps)); +} + +unittest {} diff --git a/vendor/ray/raylib.d b/vendor/ray/raylib.d new file mode 100644 index 0000000..1b07a71 --- /dev/null +++ b/vendor/ray/raylib.d @@ -0,0 +1,1695 @@ +/********************************************************************************************** +* +* raylib v5.0 - A simple and easy-to-use library to enjoy videogames programming (www.raylib.com) +* +* FEATURES: +* - NO external dependencies, all required libraries included with raylib +* - Multiplatform: Windows, Linux, FreeBSD, OpenBSD, NetBSD, DragonFly, +* MacOS, Haiku, Android, Raspberry Pi, DRM native, HTML5. +* - Written in plain C code (C99) in PascalCase/camelCase notation +* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3, 4.3 or ES2 - choose at compile) +* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl] +* - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts) +* - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC) +* - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more! +* - Flexible Materials system, supporting classic maps and PBR maps +* - Animated 3D models supported (skeletal bones animation) (IQM) +* - Shaders support, including Model shaders and Postprocessing shaders +* - Powerful math module for Vector, Matrix and Quaternion operations: [raymath] +* - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD) +* - VR stereo rendering with configurable HMD device parameters +* - Bindings to multiple programming languages available! +* +* NOTES: +* - One default Font is loaded on InitWindow()->LoadFontDefault() [core, text] +* - One default Texture2D is loaded on rlglInit(), 1x1 white pixel R8G8B8A8 [rlgl] (OpenGL 3.3 or ES2) +* - One default Shader is loaded on rlglInit()->rlLoadShaderDefault() [rlgl] (OpenGL 3.3 or ES2) +* - One default RenderBatch is loaded on rlglInit()->rlLoadRenderBatch() [rlgl] (OpenGL 3.3 or ES2) +* +* DEPENDENCIES (included): +* [rcore] rglfw (Camilla Löwy - github.com/glfw/glfw) for window/context management and input (PLATFORM_DESKTOP) +* [rlgl] glad (David Herberth - github.com/Dav1dde/glad) for OpenGL 3.3 extensions loading (PLATFORM_DESKTOP) +* [raudio] miniaudio (David Reid - github.com/mackron/miniaudio) for audio device/context management +* +* OPTIONAL DEPENDENCIES (included): +* [rcore] msf_gif (Miles Fogle) for GIF recording +* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm +* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm +* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...) +* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG) +* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms +* [rtext] stb_truetype (Sean Barret) for ttf fonts loading +* [rtext] stb_rect_pack (Sean Barret) for rectangles packing +* [rmodels] par_shapes (Philip Rideout) for parametric 3d shapes generation +* [rmodels] tinyobj_loader_c (Syoyo Fujita) for models loading (OBJ, MTL) +* [rmodels] cgltf (Johannes Kuhlmann) for models loading (glTF) +* [rmodels] Model3D (bzt) for models loading (M3D, https://bztsrc.gitlab.io/model3d) +* [raudio] dr_wav (David Reid) for WAV audio file loading +* [raudio] dr_flac (David Reid) for FLAC audio file loading +* [raudio] dr_mp3 (David Reid) for MP3 audio file loading +* [raudio] stb_vorbis (Sean Barret) for OGG audio loading +* [raudio] jar_xm (Joshua Reisenauer) for XM audio module loading +* [raudio] jar_mod (Joshua Reisenauer) for MOD audio module loading +* +* +* LICENSE: zlib/libpng +* +* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software: +* +* Copyright (c) 2013-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +module popka.vendor.ray.raylib; + +import core.stdc.config; +import core.stdc.stdarg; +import core.stdc.stdlib; + +extern (C): + +// Required for: va_list - Only used by TraceLogCallback + +enum RAYLIB_VERSION_MAJOR = 5; +enum RAYLIB_VERSION_MINOR = 0; +enum RAYLIB_VERSION_PATCH = 0; +enum RAYLIB_VERSION = "5.0"; + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll + +// We are building the library as a Win32 shared library (.dll) + +// We are using the library as a Win32 shared library (.dll) // Functions defined as 'extern' by default (implicit specifiers) + +//---------------------------------------------------------------------------------- +// Some basic Defines +//---------------------------------------------------------------------------------- + +enum PI = 3.14159265358979323846f; + +enum DEG2RAD = PI / 180.0f; + +enum RAD2DEG = 180.0f / PI; + +// Allow custom memory allocators +// NOTE: Require recompiling raylib sources + +alias RL_MALLOC = malloc; + +alias RL_CALLOC = calloc; + +alias RL_REALLOC = realloc; + +alias RL_FREE = free; + +// NOTE: MSVC C++ compiler does not support compound literals (C99 feature) +// Plain structures in C++ (without constructors) can be initialized with { } +// This is called aggregate initialization (C++11 feature) + +extern (D) auto CLITERAL(T)(auto ref T type) +{ + return type; +} + +// Some compilers (mostly macos clang) default to C++98, +// where aggregate initialization can't be used +// So, give a more clear error stating how to fix this + +// NOTE: We set some defines with some data types declared by raylib +// Other modules (raymath, rlgl) also require some of those types, so, +// to be able to use those other modules as standalone (not depending on raylib) +// this defines are very useful for internal check and avoid type (re)definitions + +// Some Basic Colors +// NOTE: Custom raylib color palette for amazing visuals on WHITE background // Light Gray // Gray // Dark Gray // Yellow // Gold // Orange // Pink // Red // Maroon // Green // Lime // Dark Green // Sky Blue // Blue // Dark Blue // Purple // Violet // Dark Purple // Beige // Brown // Dark Brown // White // Black // Blank (Transparent) // Magenta // My own White (raylib logo) +enum LIGHTGRAY = Color( 200, 200, 200, 255 ); // Light Gray +enum GRAY = Color( 130, 130, 130, 255 ); // Gray +enum DARKGRAY = Color( 80, 80, 80, 255 ); // Dark Gray +enum YELLOW = Color( 253, 249, 0, 255 ); // Yellow +enum GOLD = Color( 255, 203, 0, 255 ); // Gold +enum ORANGE = Color( 255, 161, 0, 255 ); // Orange +enum PINK = Color( 255, 109, 194, 255 ); // Pink +enum RED = Color( 230, 41, 55, 255 ); // Red +enum MAROON = Color( 190, 33, 55, 255 ); // Maroon +enum GREEN = Color( 0, 228, 48, 255 ); // Green +enum LIME = Color( 0, 158, 47, 255 ); // Lime +enum DARKGREEN = Color( 0, 117, 44, 255 ); // Dark Green +enum SKYBLUE = Color( 102, 191, 255, 255 ); // Sky Blue +enum BLUE = Color( 0, 121, 241, 255 ); // Blue +enum DARKBLUE = Color( 0, 82, 172, 255 ); // Dark Blue +enum PURPLE = Color( 200, 122, 255, 255 ); // Purple +enum VIOLET = Color( 135, 60, 190, 255 ); // Violet +enum DARKPURPLE = Color( 112, 31, 126, 255 ); // Dark Purple +enum BEIGE = Color( 211, 176, 131, 255 ); // Beige +enum BROWN = Color( 127, 106, 79, 255 ); // Brown +enum DARKBROWN = Color( 76, 63, 47, 255 ); // Dark Brown + +enum WHITE = Color( 255, 255, 255, 255 ); // White +enum BLACK = Color( 0, 0, 0, 255 ); // Black +enum BLANK = Color( 0, 0, 0, 0 ); // Blank (Transparent) +enum MAGENTA = Color( 255, 0, 255, 255 ); // Magenta +enum RAYWHITE = Color( 245, 245, 245, 255 ); // My own White (raylib logo) + +//---------------------------------------------------------------------------------- +// Structures Definition +//---------------------------------------------------------------------------------- +// Boolean type + +// Vector2, 2 components +struct Vector2 +{ + float x; // Vector x component + float y; // Vector y component +} + +// Vector3, 3 components +struct Vector3 +{ + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component +} + +// Vector4, 4 components +struct Vector4 +{ + float x; // Vector x component + float y; // Vector y component + float z; // Vector z component + float w; // Vector w component +} + +// Quaternion, 4 components (Vector4 alias) +alias Quaternion = Vector4; + +// Matrix, 4x4 components, column major, OpenGL style, right-handed +struct Matrix +{ + float m0; + float m4; + float m8; + float m12; // Matrix first row (4 components) + float m1; + float m5; + float m9; + float m13; // Matrix second row (4 components) + float m2; + float m6; + float m10; + float m14; // Matrix third row (4 components) + float m3; + float m7; + float m11; + float m15; // Matrix fourth row (4 components) +} + +// Color, 4 components, R8G8B8A8 (32bit) +struct Color +{ + ubyte r; // Color red value + ubyte g; // Color green value + ubyte b; // Color blue value + ubyte a; // Color alpha value +} + +// Rectangle, 4 components +struct Rectangle +{ + float x; // Rectangle top-left corner position x + float y; // Rectangle top-left corner position y + float width; // Rectangle width + float height; // Rectangle height +} + +// Image, pixel data stored in CPU memory (RAM) +struct Image +{ + void* data; // Image raw data + int width; // Image base width + int height; // Image base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) +} + +// Texture, tex data stored in GPU memory (VRAM) +struct Texture +{ + uint id; // OpenGL texture id + int width; // Texture base width + int height; // Texture base height + int mipmaps; // Mipmap levels, 1 by default + int format; // Data format (PixelFormat type) +} + +// Texture2D, same as Texture +alias Texture2D = Texture; + +// TextureCubemap, same as Texture +alias TextureCubemap = Texture; + +// RenderTexture, fbo for texture rendering +struct RenderTexture +{ + uint id; // OpenGL framebuffer object id + Texture texture; // Color buffer attachment texture + Texture depth; // Depth buffer attachment texture +} + +// RenderTexture2D, same as RenderTexture +alias RenderTexture2D = RenderTexture; + +// NPatchInfo, n-patch layout info +struct NPatchInfo +{ + Rectangle source; // Texture source rectangle + int left; // Left border offset + int top; // Top border offset + int right; // Right border offset + int bottom; // Bottom border offset + int layout; // Layout of the n-patch: 3x3, 1x3 or 3x1 +} + +// GlyphInfo, font characters glyphs info +struct GlyphInfo +{ + int value; // Character value (Unicode) + int offsetX; // Character offset X when drawing + int offsetY; // Character offset Y when drawing + int advanceX; // Character advance position X + Image image; // Character image data +} + +// Font, font texture and GlyphInfo array data +struct Font +{ + int baseSize; // Base size (default chars height) + int glyphCount; // Number of glyph characters + int glyphPadding; // Padding around the glyph characters + Texture2D texture; // Texture atlas containing the glyphs + Rectangle* recs; // Rectangles in texture for the glyphs + GlyphInfo* glyphs; // Glyphs info data +} + +// Camera, defines position/orientation in 3d space +struct Camera3D +{ + Vector3 position; // Camera position + Vector3 target; // Camera target it looks-at + Vector3 up; // Camera up vector (rotation over its axis) + float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic + int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC +} + +alias Camera = Camera3D; // Camera type fallback, defaults to Camera3D + +// Camera2D, defines position/orientation in 2d space +struct Camera2D +{ + Vector2 offset; // Camera offset (displacement from target) + Vector2 target; // Camera target (rotation and zoom origin) + float rotation; // Camera rotation in degrees + float zoom; // Camera zoom (scaling), should be 1.0f by default +} + +// Mesh, vertex data and vao/vbo +struct Mesh +{ + int vertexCount; // Number of vertices stored in arrays + int triangleCount; // Number of triangles stored (indexed or not) + + // Vertex attributes data + float* vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float* texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + float* texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5) + float* normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + float* tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) + ubyte* colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + ushort* indices; // Vertex indices (in case vertex data comes indexed) + + // Animation vertex data + float* animVertices; // Animated vertex positions (after bones transformations) + float* animNormals; // Animated normals (after bones transformations) + ubyte* boneIds; // Vertex bone ids, max 255 bone ids, up to 4 bones influence by vertex (skinning) + float* boneWeights; // Vertex bone weight, up to 4 bones influence by vertex (skinning) + + // OpenGL identifiers + uint vaoId; // OpenGL Vertex Array Object id + uint* vboId; // OpenGL Vertex Buffer Objects id (default vertex data) +} + +// Shader +struct Shader +{ + uint id; // Shader program id + int* locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) +} + +// MaterialMap +struct MaterialMap +{ + Texture2D texture; // Material map texture + Color color; // Material map color + float value; // Material map value +} + +// Material, includes shader and maps +struct Material +{ + Shader shader; // Material shader + MaterialMap* maps; // Material maps array (MAX_MATERIAL_MAPS) + float[4] params; // Material generic parameters (if required) +} + +// Transform, vertex transformation data +struct Transform +{ + Vector3 translation; // Translation + Quaternion rotation; // Rotation + Vector3 scale; // Scale +} + +// Bone, skeletal animation bone +struct BoneInfo +{ + char[32] name; // Bone name + int parent; // Bone parent +} + +// Model, meshes, materials and animation data +struct Model +{ + Matrix transform; // Local transform matrix + + int meshCount; // Number of meshes + int materialCount; // Number of materials + Mesh* meshes; // Meshes array + Material* materials; // Materials array + int* meshMaterial; // Mesh material number + + // Animation data + int boneCount; // Number of bones + BoneInfo* bones; // Bones information (skeleton) + Transform* bindPose; // Bones base transformation (pose) +} + +// ModelAnimation +struct ModelAnimation +{ + int boneCount; // Number of bones + int frameCount; // Number of animation frames + BoneInfo* bones; // Bones information (skeleton) + Transform** framePoses; // Poses array by frame + char[32] name; // Animation name +} + +// Ray, ray for raycasting +struct Ray +{ + Vector3 position; // Ray position (origin) + Vector3 direction; // Ray direction +} + +// RayCollision, ray hit information +struct RayCollision +{ + bool hit; // Did the ray hit something? + float distance; // Distance to the nearest hit + Vector3 point; // Point of the nearest hit + Vector3 normal; // Surface normal of hit +} + +// BoundingBox +struct BoundingBox +{ + Vector3 min; // Minimum vertex box-corner + Vector3 max; // Maximum vertex box-corner +} + +// Wave, audio wave data +struct Wave +{ + uint frameCount; // Total number of frames (considering channels) + uint sampleRate; // Frequency (samples per second) + uint sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + uint channels; // Number of channels (1-mono, 2-stereo, ...) + void* data; // Buffer data pointer +} + +// Opaque structs declaration +// NOTE: Actual structs are defined internally in raudio module +struct rAudioBuffer; +struct rAudioProcessor; + +// AudioStream, custom audio stream +struct AudioStream +{ + rAudioBuffer* buffer; // Pointer to internal data used by the audio system + rAudioProcessor* processor; // Pointer to internal data processor, useful for audio effects + + uint sampleRate; // Frequency (samples per second) + uint sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + uint channels; // Number of channels (1-mono, 2-stereo, ...) +} + +// Sound +struct Sound +{ + AudioStream stream; // Audio stream + uint frameCount; // Total number of frames (considering channels) +} + +// Music, audio stream, anything longer than ~10 seconds should be streamed +struct Music +{ + AudioStream stream; // Audio stream + uint frameCount; // Total number of frames (considering channels) + bool looping; // Music looping enable + + int ctxType; // Type of music context (audio filetype) + void* ctxData; // Audio context data, depends on type +} + +// VrDeviceInfo, Head-Mounted-Display device parameters +struct VrDeviceInfo +{ + int hResolution; // Horizontal resolution in pixels + int vResolution; // Vertical resolution in pixels + float hScreenSize; // Horizontal size in meters + float vScreenSize; // Vertical size in meters + float vScreenCenter; // Screen center in meters + float eyeToScreenDistance; // Distance between eye and display in meters + float lensSeparationDistance; // Lens separation distance in meters + float interpupillaryDistance; // IPD (distance between pupils) in meters + float[4] lensDistortionValues; // Lens distortion constant parameters + float[4] chromaAbCorrection; // Chromatic aberration correction parameters +} + +// VrStereoConfig, VR stereo rendering configuration for simulator +struct VrStereoConfig +{ + Matrix[2] projection; // VR projection matrices (per eye) + Matrix[2] viewOffset; // VR view offset matrices (per eye) + float[2] leftLensCenter; // VR left lens center + float[2] rightLensCenter; // VR right lens center + float[2] leftScreenCenter; // VR left screen center + float[2] rightScreenCenter; // VR right screen center + float[2] scale; // VR distortion scale + float[2] scaleIn; // VR distortion scale in +} + +// File path list +struct FilePathList +{ + uint capacity; // Filepaths max entries + uint count; // Filepaths entries count + char** paths; // Filepaths entries +} + +// Automation event +struct AutomationEvent +{ + uint frame; // Event frame + uint type; // Event type (AutomationEventType) + int[4] params; // Event parameters (if required) +} + +// Automation event list +struct AutomationEventList +{ + uint capacity; // Events max entries (MAX_AUTOMATION_EVENTS) + uint count; // Events entries count + AutomationEvent* events; // Events entries +} + +//---------------------------------------------------------------------------------- +// Enumerators Definition +//---------------------------------------------------------------------------------- +// System/Window config flags +// NOTE: Every bit registers one state (use it with bit masks) +// By default all flags are set to 0 +enum +{ + FLAG_VSYNC_HINT = 0x00000040, // Set to try enabling V-Sync on GPU + FLAG_FULLSCREEN_MODE = 0x00000002, // Set to run program in fullscreen + FLAG_WINDOW_RESIZABLE = 0x00000004, // Set to allow resizable window + FLAG_WINDOW_UNDECORATED = 0x00000008, // Set to disable window decoration (frame and buttons) + FLAG_WINDOW_HIDDEN = 0x00000080, // Set to hide window + FLAG_WINDOW_MINIMIZED = 0x00000200, // Set to minimize window (iconify) + FLAG_WINDOW_MAXIMIZED = 0x00000400, // Set to maximize window (expanded to monitor) + FLAG_WINDOW_UNFOCUSED = 0x00000800, // Set to window non focused + FLAG_WINDOW_TOPMOST = 0x00001000, // Set to window always on top + FLAG_WINDOW_ALWAYS_RUN = 0x00000100, // Set to allow windows running while minimized + FLAG_WINDOW_TRANSPARENT = 0x00000010, // Set to allow transparent framebuffer + FLAG_WINDOW_HIGHDPI = 0x00002000, // Set to support HighDPI + FLAG_WINDOW_MOUSE_PASSTHROUGH = 0x00004000, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + FLAG_BORDERLESS_WINDOWED_MODE = 0x00008000, // Set to run program in borderless windowed mode + FLAG_MSAA_4X_HINT = 0x00000020, // Set to try enabling MSAA 4X + FLAG_INTERLACED_HINT = 0x00010000 // Set to try enabling interlaced video format (for V3D) +} + +// Trace log level +// NOTE: Organized by priority level +enum +{ + LOG_ALL = 0, // Display all logs + LOG_TRACE = 1, // Trace logging, intended for internal use only + LOG_DEBUG = 2, // Debug logging, used for internal debugging, it should be disabled on release builds + LOG_INFO = 3, // Info logging, used for program execution info + LOG_WARNING = 4, // Warning logging, used on recoverable failures + LOG_ERROR = 5, // Error logging, used on unrecoverable failures + LOG_FATAL = 6, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + LOG_NONE = 7 // Disable logging +} + +// Keyboard keys (US keyboard layout) +// NOTE: Use GetKeyPressed() to allow redefining +// required keys for alternative layouts +enum +{ + KEY_NULL = 0, // Key: NULL, used for no key pressed + // Alphanumeric keys + KEY_APOSTROPHE = 39, // Key: ' + KEY_COMMA = 44, // Key: , + KEY_MINUS = 45, // Key: - + KEY_PERIOD = 46, // Key: . + KEY_SLASH = 47, // Key: / + KEY_ZERO = 48, // Key: 0 + KEY_ONE = 49, // Key: 1 + KEY_TWO = 50, // Key: 2 + KEY_THREE = 51, // Key: 3 + KEY_FOUR = 52, // Key: 4 + KEY_FIVE = 53, // Key: 5 + KEY_SIX = 54, // Key: 6 + KEY_SEVEN = 55, // Key: 7 + KEY_EIGHT = 56, // Key: 8 + KEY_NINE = 57, // Key: 9 + KEY_SEMICOLON = 59, // Key: ; + KEY_EQUAL = 61, // Key: = + KEY_A = 65, // Key: A | a + KEY_B = 66, // Key: B | b + KEY_C = 67, // Key: C | c + KEY_D = 68, // Key: D | d + KEY_E = 69, // Key: E | e + KEY_F = 70, // Key: F | f + KEY_G = 71, // Key: G | g + KEY_H = 72, // Key: H | h + KEY_I = 73, // Key: I | i + KEY_J = 74, // Key: J | j + KEY_K = 75, // Key: K | k + KEY_L = 76, // Key: L | l + KEY_M = 77, // Key: M | m + KEY_N = 78, // Key: N | n + KEY_O = 79, // Key: O | o + KEY_P = 80, // Key: P | p + KEY_Q = 81, // Key: Q | q + KEY_R = 82, // Key: R | r + KEY_S = 83, // Key: S | s + KEY_T = 84, // Key: T | t + KEY_U = 85, // Key: U | u + KEY_V = 86, // Key: V | v + KEY_W = 87, // Key: W | w + KEY_X = 88, // Key: X | x + KEY_Y = 89, // Key: Y | y + KEY_Z = 90, // Key: Z | z + KEY_LEFT_BRACKET = 91, // Key: [ + KEY_BACKSLASH = 92, // Key: '\' + KEY_RIGHT_BRACKET = 93, // Key: ] + KEY_GRAVE = 96, // Key: ` + // Function keys + KEY_SPACE = 32, // Key: Space + KEY_ESCAPE = 256, // Key: Esc + KEY_ENTER = 257, // Key: Enter + KEY_TAB = 258, // Key: Tab + KEY_BACKSPACE = 259, // Key: Backspace + KEY_INSERT = 260, // Key: Ins + KEY_DELETE = 261, // Key: Del + KEY_RIGHT = 262, // Key: Cursor right + KEY_LEFT = 263, // Key: Cursor left + KEY_DOWN = 264, // Key: Cursor down + KEY_UP = 265, // Key: Cursor up + KEY_PAGE_UP = 266, // Key: Page up + KEY_PAGE_DOWN = 267, // Key: Page down + KEY_HOME = 268, // Key: Home + KEY_END = 269, // Key: End + KEY_CAPS_LOCK = 280, // Key: Caps lock + KEY_SCROLL_LOCK = 281, // Key: Scroll down + KEY_NUM_LOCK = 282, // Key: Num lock + KEY_PRINT_SCREEN = 283, // Key: Print screen + KEY_PAUSE = 284, // Key: Pause + KEY_F1 = 290, // Key: F1 + KEY_F2 = 291, // Key: F2 + KEY_F3 = 292, // Key: F3 + KEY_F4 = 293, // Key: F4 + KEY_F5 = 294, // Key: F5 + KEY_F6 = 295, // Key: F6 + KEY_F7 = 296, // Key: F7 + KEY_F8 = 297, // Key: F8 + KEY_F9 = 298, // Key: F9 + KEY_F10 = 299, // Key: F10 + KEY_F11 = 300, // Key: F11 + KEY_F12 = 301, // Key: F12 + KEY_LEFT_SHIFT = 340, // Key: Shift left + KEY_LEFT_CONTROL = 341, // Key: Control left + KEY_LEFT_ALT = 342, // Key: Alt left + KEY_LEFT_SUPER = 343, // Key: Super left + KEY_RIGHT_SHIFT = 344, // Key: Shift right + KEY_RIGHT_CONTROL = 345, // Key: Control right + KEY_RIGHT_ALT = 346, // Key: Alt right + KEY_RIGHT_SUPER = 347, // Key: Super right + KEY_KB_MENU = 348, // Key: KB menu + // Keypad keys + KEY_KP_0 = 320, // Key: Keypad 0 + KEY_KP_1 = 321, // Key: Keypad 1 + KEY_KP_2 = 322, // Key: Keypad 2 + KEY_KP_3 = 323, // Key: Keypad 3 + KEY_KP_4 = 324, // Key: Keypad 4 + KEY_KP_5 = 325, // Key: Keypad 5 + KEY_KP_6 = 326, // Key: Keypad 6 + KEY_KP_7 = 327, // Key: Keypad 7 + KEY_KP_8 = 328, // Key: Keypad 8 + KEY_KP_9 = 329, // Key: Keypad 9 + KEY_KP_DECIMAL = 330, // Key: Keypad . + KEY_KP_DIVIDE = 331, // Key: Keypad / + KEY_KP_MULTIPLY = 332, // Key: Keypad * + KEY_KP_SUBTRACT = 333, // Key: Keypad - + KEY_KP_ADD = 334, // Key: Keypad + + KEY_KP_ENTER = 335, // Key: Keypad Enter + KEY_KP_EQUAL = 336, // Key: Keypad = + // Android key buttons + KEY_BACK = 4, // Key: Android back button + KEY_MENU = 82, // Key: Android menu button + KEY_VOLUME_UP = 24, // Key: Android volume up button + KEY_VOLUME_DOWN = 25 // Key: Android volume down button +} + +// Add backwards compatibility support for deprecated names +enum MOUSE_LEFT_BUTTON = MOUSE_BUTTON_LEFT; +enum MOUSE_RIGHT_BUTTON = MOUSE_BUTTON_RIGHT; +enum MOUSE_MIDDLE_BUTTON = MOUSE_BUTTON_MIDDLE; + +// Mouse buttons +enum +{ + MOUSE_BUTTON_LEFT = 0, // Mouse button left + MOUSE_BUTTON_RIGHT = 1, // Mouse button right + MOUSE_BUTTON_MIDDLE = 2, // Mouse button middle (pressed wheel) + MOUSE_BUTTON_SIDE = 3, // Mouse button side (advanced mouse device) + MOUSE_BUTTON_EXTRA = 4, // Mouse button extra (advanced mouse device) + MOUSE_BUTTON_FORWARD = 5, // Mouse button forward (advanced mouse device) + MOUSE_BUTTON_BACK = 6 // Mouse button back (advanced mouse device) +} + +// Mouse cursor +enum +{ + MOUSE_CURSOR_DEFAULT = 0, // Default pointer shape + MOUSE_CURSOR_ARROW = 1, // Arrow shape + MOUSE_CURSOR_IBEAM = 2, // Text writing cursor shape + MOUSE_CURSOR_CROSSHAIR = 3, // Cross shape + MOUSE_CURSOR_POINTING_HAND = 4, // Pointing hand cursor + MOUSE_CURSOR_RESIZE_EW = 5, // Horizontal resize/move arrow shape + MOUSE_CURSOR_RESIZE_NS = 6, // Vertical resize/move arrow shape + MOUSE_CURSOR_RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape + MOUSE_CURSOR_RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape + MOUSE_CURSOR_RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape + MOUSE_CURSOR_NOT_ALLOWED = 10 // The operation-not-allowed shape +} + +// Gamepad buttons +enum +{ + GAMEPAD_BUTTON_UNKNOWN = 0, // Unknown button, just for error checking + GAMEPAD_BUTTON_LEFT_FACE_UP = 1, // Gamepad left DPAD up button + GAMEPAD_BUTTON_LEFT_FACE_RIGHT = 2, // Gamepad left DPAD right button + GAMEPAD_BUTTON_LEFT_FACE_DOWN = 3, // Gamepad left DPAD down button + GAMEPAD_BUTTON_LEFT_FACE_LEFT = 4, // Gamepad left DPAD left button + GAMEPAD_BUTTON_RIGHT_FACE_UP = 5, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + GAMEPAD_BUTTON_RIGHT_FACE_RIGHT = 6, // Gamepad right button right (i.e. PS3: Square, Xbox: X) + GAMEPAD_BUTTON_RIGHT_FACE_DOWN = 7, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) + GAMEPAD_BUTTON_RIGHT_FACE_LEFT = 8, // Gamepad right button left (i.e. PS3: Circle, Xbox: B) + GAMEPAD_BUTTON_LEFT_TRIGGER_1 = 9, // Gamepad top/back trigger left (first), it could be a trailing button + GAMEPAD_BUTTON_LEFT_TRIGGER_2 = 10, // Gamepad top/back trigger left (second), it could be a trailing button + GAMEPAD_BUTTON_RIGHT_TRIGGER_1 = 11, // Gamepad top/back trigger right (one), it could be a trailing button + GAMEPAD_BUTTON_RIGHT_TRIGGER_2 = 12, // Gamepad top/back trigger right (second), it could be a trailing button + GAMEPAD_BUTTON_MIDDLE_LEFT = 13, // Gamepad center buttons, left one (i.e. PS3: Select) + GAMEPAD_BUTTON_MIDDLE = 14, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + GAMEPAD_BUTTON_MIDDLE_RIGHT = 15, // Gamepad center buttons, right one (i.e. PS3: Start) + GAMEPAD_BUTTON_LEFT_THUMB = 16, // Gamepad joystick pressed button left + GAMEPAD_BUTTON_RIGHT_THUMB = 17 // Gamepad joystick pressed button right +} + +// Gamepad axis +enum +{ + GAMEPAD_AXIS_LEFT_X = 0, // Gamepad left stick X axis + GAMEPAD_AXIS_LEFT_Y = 1, // Gamepad left stick Y axis + GAMEPAD_AXIS_RIGHT_X = 2, // Gamepad right stick X axis + GAMEPAD_AXIS_RIGHT_Y = 3, // Gamepad right stick Y axis + GAMEPAD_AXIS_LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] + GAMEPAD_AXIS_RIGHT_TRIGGER = 5 // Gamepad back trigger right, pressure level: [1..-1] +} + +// Material map index +enum +{ + MATERIAL_MAP_ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) + MATERIAL_MAP_METALNESS = 1, // Metalness material (same as: MATERIAL_MAP_SPECULAR) + MATERIAL_MAP_NORMAL = 2, // Normal material + MATERIAL_MAP_ROUGHNESS = 3, // Roughness material + MATERIAL_MAP_OCCLUSION = 4, // Ambient occlusion material + MATERIAL_MAP_EMISSION = 5, // Emission material + MATERIAL_MAP_HEIGHT = 6, // Heightmap material + MATERIAL_MAP_CUBEMAP = 7, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_IRRADIANCE = 8, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_PREFILTER = 9, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + MATERIAL_MAP_BRDF = 10 // Brdf material +} + +enum MATERIAL_MAP_DIFFUSE = MATERIAL_MAP_ALBEDO; +enum MATERIAL_MAP_SPECULAR = MATERIAL_MAP_METALNESS; + +// Shader location index +enum +{ + SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + SHADER_LOC_VERTEX_TEXCOORD01 = 1, // Shader location: vertex attribute: texcoord01 + SHADER_LOC_VERTEX_TEXCOORD02 = 2, // Shader location: vertex attribute: texcoord02 + SHADER_LOC_VERTEX_NORMAL = 3, // Shader location: vertex attribute: normal + SHADER_LOC_VERTEX_TANGENT = 4, // Shader location: vertex attribute: tangent + SHADER_LOC_VERTEX_COLOR = 5, // Shader location: vertex attribute: color + SHADER_LOC_MATRIX_MVP = 6, // Shader location: matrix uniform: model-view-projection + SHADER_LOC_MATRIX_VIEW = 7, // Shader location: matrix uniform: view (camera transform) + SHADER_LOC_MATRIX_PROJECTION = 8, // Shader location: matrix uniform: projection + SHADER_LOC_MATRIX_MODEL = 9, // Shader location: matrix uniform: model (transform) + SHADER_LOC_MATRIX_NORMAL = 10, // Shader location: matrix uniform: normal + SHADER_LOC_VECTOR_VIEW = 11, // Shader location: vector uniform: view + SHADER_LOC_COLOR_DIFFUSE = 12, // Shader location: vector uniform: diffuse color + SHADER_LOC_COLOR_SPECULAR = 13, // Shader location: vector uniform: specular color + SHADER_LOC_COLOR_AMBIENT = 14, // Shader location: vector uniform: ambient color + SHADER_LOC_MAP_ALBEDO = 15, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + SHADER_LOC_MAP_METALNESS = 16, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + SHADER_LOC_MAP_NORMAL = 17, // Shader location: sampler2d texture: normal + SHADER_LOC_MAP_ROUGHNESS = 18, // Shader location: sampler2d texture: roughness + SHADER_LOC_MAP_OCCLUSION = 19, // Shader location: sampler2d texture: occlusion + SHADER_LOC_MAP_EMISSION = 20, // Shader location: sampler2d texture: emission + SHADER_LOC_MAP_HEIGHT = 21, // Shader location: sampler2d texture: height + SHADER_LOC_MAP_CUBEMAP = 22, // Shader location: samplerCube texture: cubemap + SHADER_LOC_MAP_IRRADIANCE = 23, // Shader location: samplerCube texture: irradiance + SHADER_LOC_MAP_PREFILTER = 24, // Shader location: samplerCube texture: prefilter + SHADER_LOC_MAP_BRDF = 25 // Shader location: sampler2d texture: brdf +} + +enum SHADER_LOC_MAP_DIFFUSE = SHADER_LOC_MAP_ALBEDO; +enum SHADER_LOC_MAP_SPECULAR = SHADER_LOC_MAP_METALNESS; + +// Shader uniform data type +enum +{ + SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + SHADER_UNIFORM_VEC2 = 1, // Shader uniform type: vec2 (2 float) + SHADER_UNIFORM_VEC3 = 2, // Shader uniform type: vec3 (3 float) + SHADER_UNIFORM_VEC4 = 3, // Shader uniform type: vec4 (4 float) + SHADER_UNIFORM_INT = 4, // Shader uniform type: int + SHADER_UNIFORM_IVEC2 = 5, // Shader uniform type: ivec2 (2 int) + SHADER_UNIFORM_IVEC3 = 6, // Shader uniform type: ivec3 (3 int) + SHADER_UNIFORM_IVEC4 = 7, // Shader uniform type: ivec4 (4 int) + SHADER_UNIFORM_SAMPLER2D = 8 // Shader uniform type: sampler2d +} + +// Shader attribute data types +enum +{ + SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + SHADER_ATTRIB_VEC2 = 1, // Shader attribute type: vec2 (2 float) + SHADER_ATTRIB_VEC3 = 2, // Shader attribute type: vec3 (3 float) + SHADER_ATTRIB_VEC4 = 3 // Shader attribute type: vec4 (4 float) +} + +// Pixel formats +// NOTE: Support depends on OpenGL version and platform +enum +{ + PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA = 2, // 8*2 bpp (2 channels) + PIXELFORMAT_UNCOMPRESSED_R5G6B5 = 3, // 16 bpp + PIXELFORMAT_UNCOMPRESSED_R8G8B8 = 4, // 24 bpp + PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 = 5, // 16 bpp (1 bit alpha) + PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 = 6, // 16 bpp (4 bit alpha) + PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 = 7, // 32 bpp + PIXELFORMAT_UNCOMPRESSED_R32 = 8, // 32 bpp (1 channel - float) + PIXELFORMAT_UNCOMPRESSED_R32G32B32 = 9, // 32*3 bpp (3 channels - float) + PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 = 10, // 32*4 bpp (4 channels - float) + PIXELFORMAT_UNCOMPRESSED_R16 = 11, // 16 bpp (1 channel - half float) + PIXELFORMAT_UNCOMPRESSED_R16G16B16 = 12, // 16*3 bpp (3 channels - half float) + PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 = 13, // 16*4 bpp (4 channels - half float) + PIXELFORMAT_COMPRESSED_DXT1_RGB = 14, // 4 bpp (no alpha) + PIXELFORMAT_COMPRESSED_DXT1_RGBA = 15, // 4 bpp (1 bit alpha) + PIXELFORMAT_COMPRESSED_DXT3_RGBA = 16, // 8 bpp + PIXELFORMAT_COMPRESSED_DXT5_RGBA = 17, // 8 bpp + PIXELFORMAT_COMPRESSED_ETC1_RGB = 18, // 4 bpp + PIXELFORMAT_COMPRESSED_ETC2_RGB = 19, // 4 bpp + PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA = 20, // 8 bpp + PIXELFORMAT_COMPRESSED_PVRT_RGB = 21, // 4 bpp + PIXELFORMAT_COMPRESSED_PVRT_RGBA = 22, // 4 bpp + PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA = 23, // 8 bpp + PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24 // 2 bpp +} + +// Texture parameters: filter mode +// NOTE 1: Filtering considers mipmaps if available in the texture +// NOTE 2: Filter is accordingly set for minification and magnification +enum +{ + TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + TEXTURE_FILTER_BILINEAR = 1, // Linear filtering + TEXTURE_FILTER_TRILINEAR = 2, // Trilinear filtering (linear with mipmaps) + TEXTURE_FILTER_ANISOTROPIC_4X = 3, // Anisotropic filtering 4x + TEXTURE_FILTER_ANISOTROPIC_8X = 4, // Anisotropic filtering 8x + TEXTURE_FILTER_ANISOTROPIC_16X = 5 // Anisotropic filtering 16x +} + +// Texture parameters: wrap mode +enum +{ + TEXTURE_WRAP_REPEAT = 0, // Repeats texture in tiled mode + TEXTURE_WRAP_CLAMP = 1, // Clamps texture to edge pixel in tiled mode + TEXTURE_WRAP_MIRROR_REPEAT = 2, // Mirrors and repeats the texture in tiled mode + TEXTURE_WRAP_MIRROR_CLAMP = 3 // Mirrors and clamps to border the texture in tiled mode +} + +// Cubemap layouts +enum +{ + CUBEMAP_LAYOUT_AUTO_DETECT = 0, // Automatically detect layout type + CUBEMAP_LAYOUT_LINE_VERTICAL = 1, // Layout is defined by a vertical line with faces + CUBEMAP_LAYOUT_LINE_HORIZONTAL = 2, // Layout is defined by a horizontal line with faces + CUBEMAP_LAYOUT_CROSS_THREE_BY_FOUR = 3, // Layout is defined by a 3x4 cross with cubemap faces + CUBEMAP_LAYOUT_CROSS_FOUR_BY_THREE = 4, // Layout is defined by a 4x3 cross with cubemap faces + CUBEMAP_LAYOUT_PANORAMA = 5 // Layout is defined by a panorama image (equirrectangular map) +} + +// Font type, defines generation method +enum +{ + FONT_DEFAULT = 0, // Default font generation, anti-aliased + FONT_BITMAP = 1, // Bitmap font generation, no anti-aliasing + FONT_SDF = 2 // SDF font generation, requires external shader +} + +// Color blending modes (pre-defined) +enum +{ + BLEND_ALPHA = 0, // Blend textures considering alpha (default) + BLEND_ADDITIVE = 1, // Blend textures adding colors + BLEND_MULTIPLIED = 2, // Blend textures multiplying colors + BLEND_ADD_COLORS = 3, // Blend textures adding colors (alternative) + BLEND_SUBTRACT_COLORS = 4, // Blend textures subtracting colors (alternative) + BLEND_ALPHA_PREMULTIPLY = 5, // Blend premultiplied textures considering alpha + BLEND_CUSTOM = 6, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + BLEND_CUSTOM_SEPARATE = 7 // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) +} + +// Gesture +// NOTE: Provided as bit-wise flags to enable only desired gestures +enum +{ + GESTURE_NONE = 0, // No gesture + GESTURE_TAP = 1, // Tap gesture + GESTURE_DOUBLETAP = 2, // Double tap gesture + GESTURE_HOLD = 4, // Hold gesture + GESTURE_DRAG = 8, // Drag gesture + GESTURE_SWIPE_RIGHT = 16, // Swipe right gesture + GESTURE_SWIPE_LEFT = 32, // Swipe left gesture + GESTURE_SWIPE_UP = 64, // Swipe up gesture + GESTURE_SWIPE_DOWN = 128, // Swipe down gesture + GESTURE_PINCH_IN = 256, // Pinch in gesture + GESTURE_PINCH_OUT = 512 // Pinch out gesture +} + +// Camera system modes +enum +{ + CAMERA_CUSTOM = 0, // Custom camera + CAMERA_FREE = 1, // Free camera + CAMERA_ORBITAL = 2, // Orbital camera + CAMERA_FIRST_PERSON = 3, // First person camera + CAMERA_THIRD_PERSON = 4 // Third person camera +} + +// Camera projection +enum +{ + CAMERA_PERSPECTIVE = 0, // Perspective projection + CAMERA_ORTHOGRAPHIC = 1 // Orthographic projection +} + +// N-patch layout +enum +{ + NPATCH_NINE_PATCH = 0, // Npatch layout: 3x3 tiles + NPATCH_THREE_PATCH_VERTICAL = 1, // Npatch layout: 1x3 tiles + NPATCH_THREE_PATCH_HORIZONTAL = 2 // Npatch layout: 3x1 tiles +} + +// Callbacks to hook some internal functions +// WARNING: These callbacks are intended for advance users +alias TraceLogCallback = void function (int logLevel, const(char)* text, va_list args); // Logging: Redirect trace log messages +alias LoadFileDataCallback = ubyte* function (const(char)* fileName, int* dataSize); // FileIO: Load binary data +alias SaveFileDataCallback = bool function (const(char)* fileName, void* data, int dataSize); // FileIO: Save binary data +alias LoadFileTextCallback = char* function (const(char)* fileName); // FileIO: Load text data +alias SaveFileTextCallback = bool function (const(char)* fileName, char* text); // FileIO: Save text data + +//------------------------------------------------------------------------------------ +// Global Variables Definition +//------------------------------------------------------------------------------------ +// It's lonely here... + +//------------------------------------------------------------------------------------ +// Window and Graphics Device Functions (Module: core) +//------------------------------------------------------------------------------------ + +// Prevents name mangling of functions + +// Window-related functions +void InitWindow (int width, int height, const(char)* title); // Initialize window and OpenGL context +void CloseWindow (); // Close window and unload OpenGL context +bool WindowShouldClose (); // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) +bool IsWindowReady (); // Check if window has been initialized successfully +bool IsWindowFullscreen (); // Check if window is currently fullscreen +bool IsWindowHidden (); // Check if window is currently hidden (only PLATFORM_DESKTOP) +bool IsWindowMinimized (); // Check if window is currently minimized (only PLATFORM_DESKTOP) +bool IsWindowMaximized (); // Check if window is currently maximized (only PLATFORM_DESKTOP) +bool IsWindowFocused (); // Check if window is currently focused (only PLATFORM_DESKTOP) +bool IsWindowResized (); // Check if window has been resized last frame +bool IsWindowState (uint flag); // Check if one specific window flag is enabled +void SetWindowState (uint flags); // Set window configuration state using flags (only PLATFORM_DESKTOP) +void ClearWindowState (uint flags); // Clear window configuration state flags +void ToggleFullscreen (); // Toggle window state: fullscreen/windowed (only PLATFORM_DESKTOP) +void ToggleBorderlessWindowed (); // Toggle window state: borderless windowed (only PLATFORM_DESKTOP) +void MaximizeWindow (); // Set window state: maximized, if resizable (only PLATFORM_DESKTOP) +void MinimizeWindow (); // Set window state: minimized, if resizable (only PLATFORM_DESKTOP) +void RestoreWindow (); // Set window state: not minimized/maximized (only PLATFORM_DESKTOP) +void SetWindowIcon (Image image); // Set icon for window (single image, RGBA 32bit, only PLATFORM_DESKTOP) +void SetWindowIcons (Image* images, int count); // Set icon for window (multiple images, RGBA 32bit, only PLATFORM_DESKTOP) +void SetWindowTitle (const(char)* title); // Set title for window (only PLATFORM_DESKTOP and PLATFORM_WEB) +void SetWindowPosition (int x, int y); // Set window position on screen (only PLATFORM_DESKTOP) +void SetWindowMonitor (int monitor); // Set monitor for the current window +void SetWindowMinSize (int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE) +void SetWindowMaxSize (int width, int height); // Set window maximum dimensions (for FLAG_WINDOW_RESIZABLE) +void SetWindowSize (int width, int height); // Set window dimensions +void SetWindowOpacity (float opacity); // Set window opacity [0.0f..1.0f] (only PLATFORM_DESKTOP) +void SetWindowFocused (); // Set window focused (only PLATFORM_DESKTOP) +void* GetWindowHandle (); // Get native window handle +int GetScreenWidth (); // Get current screen width +int GetScreenHeight (); // Get current screen height +int GetRenderWidth (); // Get current render width (it considers HiDPI) +int GetRenderHeight (); // Get current render height (it considers HiDPI) +int GetMonitorCount (); // Get number of connected monitors +int GetCurrentMonitor (); // Get current connected monitor +Vector2 GetMonitorPosition (int monitor); // Get specified monitor position +int GetMonitorWidth (int monitor); // Get specified monitor width (current video mode used by monitor) +int GetMonitorHeight (int monitor); // Get specified monitor height (current video mode used by monitor) +int GetMonitorPhysicalWidth (int monitor); // Get specified monitor physical width in millimetres +int GetMonitorPhysicalHeight (int monitor); // Get specified monitor physical height in millimetres +int GetMonitorRefreshRate (int monitor); // Get specified monitor refresh rate +Vector2 GetWindowPosition (); // Get window position XY on monitor +Vector2 GetWindowScaleDPI (); // Get window scale DPI factor +const(char)* GetMonitorName (int monitor); // Get the human-readable, UTF-8 encoded name of the specified monitor +void SetClipboardText (const(char)* text); // Set clipboard text content +const(char)* GetClipboardText (); // Get clipboard text content +void EnableEventWaiting (); // Enable waiting for events on EndDrawing(), no automatic event polling +void DisableEventWaiting (); // Disable waiting for events on EndDrawing(), automatic events polling + +// Cursor-related functions +void ShowCursor (); // Shows cursor +void HideCursor (); // Hides cursor +bool IsCursorHidden (); // Check if cursor is not visible +void EnableCursor (); // Enables cursor (unlock cursor) +void DisableCursor (); // Disables cursor (lock cursor) +bool IsCursorOnScreen (); // Check if cursor is on the screen + +// Drawing-related functions +void ClearBackground (Color color); // Set background color (framebuffer clear color) +void BeginDrawing (); // Setup canvas (framebuffer) to start drawing +void EndDrawing (); // End canvas drawing and swap buffers (double buffering) +void BeginMode2D (Camera2D camera); // Begin 2D mode with custom camera (2D) +void EndMode2D (); // Ends 2D mode with custom camera +void BeginMode3D (Camera3D camera); // Begin 3D mode with custom camera (3D) +void EndMode3D (); // Ends 3D mode and returns to default 2D orthographic mode +void BeginTextureMode (RenderTexture2D target); // Begin drawing to render texture +void EndTextureMode (); // Ends drawing to render texture +void BeginShaderMode (Shader shader); // Begin custom shader drawing +void EndShaderMode (); // End custom shader drawing (use default shader) +void BeginBlendMode (int mode); // Begin blending mode (alpha, additive, multiplied, subtract, custom) +void EndBlendMode (); // End blending mode (reset to default: alpha blending) +void BeginScissorMode (int x, int y, int width, int height); // Begin scissor mode (define screen area for following drawing) +void EndScissorMode (); // End scissor mode +void BeginVrStereoMode (VrStereoConfig config); // Begin stereo rendering (requires VR simulator) +void EndVrStereoMode (); // End stereo rendering (requires VR simulator) + +// VR stereo config functions for VR simulator +VrStereoConfig LoadVrStereoConfig (VrDeviceInfo device); // Load VR stereo config for VR simulator device parameters +void UnloadVrStereoConfig (VrStereoConfig config); // Unload VR stereo config + +// Shader management functions +// NOTE: Shader functionality is not available on OpenGL 1.1 +Shader LoadShader (const(char)* vsFileName, const(char)* fsFileName); // Load shader from files and bind default locations +Shader LoadShaderFromMemory (const(char)* vsCode, const(char)* fsCode); // Load shader from code strings and bind default locations +bool IsShaderReady (Shader shader); // Check if a shader is ready +int GetShaderLocation (Shader shader, const(char)* uniformName); // Get shader uniform location +int GetShaderLocationAttrib (Shader shader, const(char)* attribName); // Get shader attribute location +void SetShaderValue (Shader shader, int locIndex, const(void)* value, int uniformType); // Set shader uniform value +void SetShaderValueV (Shader shader, int locIndex, const(void)* value, int uniformType, int count); // Set shader uniform value vector +void SetShaderValueMatrix (Shader shader, int locIndex, Matrix mat); // Set shader uniform value (matrix 4x4) +void SetShaderValueTexture (Shader shader, int locIndex, Texture2D texture); // Set shader uniform value for texture (sampler2d) +void UnloadShader (Shader shader); // Unload shader from GPU memory (VRAM) + +// Screen-space-related functions +Ray GetMouseRay (Vector2 mousePosition, Camera camera); // Get a ray trace from mouse position +Matrix GetCameraMatrix (Camera camera); // Get camera transform matrix (view matrix) +Matrix GetCameraMatrix2D (Camera2D camera); // Get camera 2d transform matrix +Vector2 GetWorldToScreen (Vector3 position, Camera camera); // Get the screen space position for a 3d world space position +Vector2 GetScreenToWorld2D (Vector2 position, Camera2D camera); // Get the world space position for a 2d camera screen space position +Vector2 GetWorldToScreenEx (Vector3 position, Camera camera, int width, int height); // Get size position for a 3d world space position +Vector2 GetWorldToScreen2D (Vector2 position, Camera2D camera); // Get the screen space position for a 2d camera world space position + +// Timing-related functions +void SetTargetFPS (int fps); // Set target FPS (maximum) +float GetFrameTime (); // Get time in seconds for last frame drawn (delta time) +double GetTime (); // Get elapsed time in seconds since InitWindow() +int GetFPS (); // Get current FPS + +// Custom frame control functions +// NOTE: Those functions are intended for advance users that want full control over the frame processing +// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents() +// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL +void SwapScreenBuffer (); // Swap back buffer with front buffer (screen drawing) +void PollInputEvents (); // Register all input events +void WaitTime (double seconds); // Wait for some time (halt program execution) + +// Random values generation functions +void SetRandomSeed (uint seed); // Set the seed for the random number generator +int GetRandomValue (int min, int max); // Get a random value between min and max (both included) +int* LoadRandomSequence (uint count, int min, int max); // Load random values sequence, no values repeated +void UnloadRandomSequence (int* sequence); // Unload random values sequence + +// Misc. functions +void TakeScreenshot (const(char)* fileName); // Takes a screenshot of current screen (filename extension defines format) +void SetConfigFlags (uint flags); // Setup init configuration flags (view FLAGS) +void OpenURL (const(char)* url); // Open URL with default system browser (if available) + +// NOTE: Following functions implemented in module [utils] +//------------------------------------------------------------------ +void TraceLog (int logLevel, const(char)* text, ...); // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...) +void SetTraceLogLevel (int logLevel); // Set the current threshold (minimum) log level +void* MemAlloc (uint size); // Internal memory allocator +void* MemRealloc (void* ptr, uint size); // Internal memory reallocator +void MemFree (void* ptr); // Internal memory free + +// Set custom callbacks +// WARNING: Callbacks setup is intended for advance users +void SetTraceLogCallback (TraceLogCallback callback); // Set custom trace log +void SetLoadFileDataCallback (LoadFileDataCallback callback); // Set custom file binary data loader +void SetSaveFileDataCallback (SaveFileDataCallback callback); // Set custom file binary data saver +void SetLoadFileTextCallback (LoadFileTextCallback callback); // Set custom file text data loader +void SetSaveFileTextCallback (SaveFileTextCallback callback); // Set custom file text data saver + +// Files management functions +ubyte* LoadFileData (const(char)* fileName, int* dataSize); // Load file data as byte array (read) +void UnloadFileData (ubyte* data); // Unload file data allocated by LoadFileData() +bool SaveFileData (const(char)* fileName, void* data, int dataSize); // Save data to file from byte array (write), returns true on success +bool ExportDataAsCode (const(ubyte)* data, int dataSize, const(char)* fileName); // Export data to code (.h), returns true on success +char* LoadFileText (const(char)* fileName); // Load text data from file (read), returns a '\0' terminated string +void UnloadFileText (char* text); // Unload file text data allocated by LoadFileText() +bool SaveFileText (const(char)* fileName, char* text); // Save text data to file (write), string must be '\0' terminated, returns true on success +//------------------------------------------------------------------ + +// File system functions +bool FileExists (const(char)* fileName); // Check if file exists +bool DirectoryExists (const(char)* dirPath); // Check if a directory path exists +bool IsFileExtension (const(char)* fileName, const(char)* ext); // Check file extension (including point: .png, .wav) +int GetFileLength (const(char)* fileName); // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) +const(char)* GetFileExtension (const(char)* fileName); // Get pointer to extension for a filename string (includes dot: '.png') +const(char)* GetFileName (const(char)* filePath); // Get pointer to filename for a path string +const(char)* GetFileNameWithoutExt (const(char)* filePath); // Get filename string without extension (uses static string) +const(char)* GetDirectoryPath (const(char)* filePath); // Get full path for a given fileName with path (uses static string) +const(char)* GetPrevDirectoryPath (const(char)* dirPath); // Get previous directory path for a given path (uses static string) +const(char)* GetWorkingDirectory (); // Get current working directory (uses static string) +const(char)* GetApplicationDirectory (); // Get the directory of the running application (uses static string) +bool ChangeDirectory (const(char)* dir); // Change working directory, return true on success +bool IsPathFile (const(char)* path); // Check if a given path is a file or a directory +FilePathList LoadDirectoryFiles (const(char)* dirPath); // Load directory filepaths +FilePathList LoadDirectoryFilesEx (const(char)* basePath, const(char)* filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan +void UnloadDirectoryFiles (FilePathList files); // Unload filepaths +bool IsFileDropped (); // Check if a file has been dropped into window +FilePathList LoadDroppedFiles (); // Load dropped filepaths +void UnloadDroppedFiles (FilePathList files); // Unload dropped filepaths +c_long GetFileModTime (const(char)* fileName); // Get file modification time (last write time) + +// Compression/Encoding functionality +ubyte* CompressData (const(ubyte)* data, int dataSize, int* compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() +ubyte* DecompressData (const(ubyte)* compData, int compDataSize, int* dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree() +char* EncodeDataBase64 (const(ubyte)* data, int dataSize, int* outputSize); // Encode data to Base64 string, memory must be MemFree() +ubyte* DecodeDataBase64 (const(ubyte)* data, int* outputSize); // Decode Base64 string data, memory must be MemFree() + +// Automation events functionality +AutomationEventList LoadAutomationEventList (const(char)* fileName); // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS +void UnloadAutomationEventList (AutomationEventList* list); // Unload automation events list from file +bool ExportAutomationEventList (AutomationEventList list, const(char)* fileName); // Export automation events list as text file +void SetAutomationEventList (AutomationEventList* list); // Set automation event list to record to +void SetAutomationEventBaseFrame (int frame); // Set automation event internal base frame to start recording +void StartAutomationEventRecording (); // Start recording automation events (AutomationEventList must be set) +void StopAutomationEventRecording (); // Stop recording automation events +void PlayAutomationEvent (AutomationEvent event); // Play a recorded automation event + +//------------------------------------------------------------------------------------ +// Input Handling Functions (Module: core) +//------------------------------------------------------------------------------------ + +// Input-related functions: keyboard +bool IsKeyPressed (int key); // Check if a key has been pressed once +bool IsKeyPressedRepeat (int key); // Check if a key has been pressed again (Only PLATFORM_DESKTOP) +bool IsKeyDown (int key); // Check if a key is being pressed +bool IsKeyReleased (int key); // Check if a key has been released once +bool IsKeyUp (int key); // Check if a key is NOT being pressed +int GetKeyPressed (); // Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty +int GetCharPressed (); // Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty +void SetExitKey (int key); // Set a custom key to exit program (default is ESC) + +// Input-related functions: gamepads +bool IsGamepadAvailable (int gamepad); // Check if a gamepad is available +const(char)* GetGamepadName (int gamepad); // Get gamepad internal name id +bool IsGamepadButtonPressed (int gamepad, int button); // Check if a gamepad button has been pressed once +bool IsGamepadButtonDown (int gamepad, int button); // Check if a gamepad button is being pressed +bool IsGamepadButtonReleased (int gamepad, int button); // Check if a gamepad button has been released once +bool IsGamepadButtonUp (int gamepad, int button); // Check if a gamepad button is NOT being pressed +int GetGamepadButtonPressed (); // Get the last gamepad button pressed +int GetGamepadAxisCount (int gamepad); // Get gamepad axis count for a gamepad +float GetGamepadAxisMovement (int gamepad, int axis); // Get axis movement value for a gamepad axis +int SetGamepadMappings (const(char)* mappings); // Set internal gamepad mappings (SDL_GameControllerDB) + +// Input-related functions: mouse +bool IsMouseButtonPressed (int button); // Check if a mouse button has been pressed once +bool IsMouseButtonDown (int button); // Check if a mouse button is being pressed +bool IsMouseButtonReleased (int button); // Check if a mouse button has been released once +bool IsMouseButtonUp (int button); // Check if a mouse button is NOT being pressed +int GetMouseX (); // Get mouse position X +int GetMouseY (); // Get mouse position Y +Vector2 GetMousePosition (); // Get mouse position XY +Vector2 GetMouseDelta (); // Get mouse delta between frames +void SetMousePosition (int x, int y); // Set mouse position XY +void SetMouseOffset (int offsetX, int offsetY); // Set mouse offset +void SetMouseScale (float scaleX, float scaleY); // Set mouse scaling +float GetMouseWheelMove (); // Get mouse wheel movement for X or Y, whichever is larger +Vector2 GetMouseWheelMoveV (); // Get mouse wheel movement for both X and Y +void SetMouseCursor (int cursor); // Set mouse cursor + +// Input-related functions: touch +int GetTouchX (); // Get touch position X for touch point 0 (relative to screen size) +int GetTouchY (); // Get touch position Y for touch point 0 (relative to screen size) +Vector2 GetTouchPosition (int index); // Get touch position XY for a touch point index (relative to screen size) +int GetTouchPointId (int index); // Get touch point identifier for given index +int GetTouchPointCount (); // Get number of touch points + +//------------------------------------------------------------------------------------ +// Gestures and Touch Handling Functions (Module: rgestures) +//------------------------------------------------------------------------------------ +void SetGesturesEnabled (uint flags); // Enable a set of gestures using flags +bool IsGestureDetected (uint gesture); // Check if a gesture have been detected +int GetGestureDetected (); // Get latest detected gesture +float GetGestureHoldDuration (); // Get gesture hold time in milliseconds +Vector2 GetGestureDragVector (); // Get gesture drag vector +float GetGestureDragAngle (); // Get gesture drag angle +Vector2 GetGesturePinchVector (); // Get gesture pinch delta +float GetGesturePinchAngle (); // Get gesture pinch angle + +//------------------------------------------------------------------------------------ +// Camera System Functions (Module: rcamera) +//------------------------------------------------------------------------------------ +void UpdateCamera (Camera* camera, int mode); // Update camera position for selected mode +void UpdateCameraPro (Camera* camera, Vector3 movement, Vector3 rotation, float zoom); // Update camera movement/rotation + +//------------------------------------------------------------------------------------ +// Basic Shapes Drawing Functions (Module: shapes) +//------------------------------------------------------------------------------------ +// Set texture and rectangle to be used on shapes drawing +// NOTE: It can be useful when using basic shapes and one single font, +// defining a font char white rectangle would allow drawing everything in a single draw call +void SetShapesTexture (Texture2D texture, Rectangle source); // Set texture and rectangle to be used on shapes drawing + +// Basic shapes drawing functions +void DrawPixel (int posX, int posY, Color color); // Draw a pixel +void DrawPixelV (Vector2 position, Color color); // Draw a pixel (Vector version) +void DrawLine (int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line +void DrawLineV (Vector2 startPos, Vector2 endPos, Color color); // Draw a line (using gl lines) +void DrawLineEx (Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line (using triangles/quads) +void DrawLineStrip (Vector2* points, int pointCount, Color color); // Draw lines sequence (using gl lines) +void DrawLineBezier (Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation +void DrawCircle (int centerX, int centerY, float radius, Color color); // Draw a color-filled circle +void DrawCircleSector (Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle +void DrawCircleSectorLines (Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline +void DrawCircleGradient (int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle +void DrawCircleV (Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version) +void DrawCircleLines (int centerX, int centerY, float radius, Color color); // Draw circle outline +void DrawCircleLinesV (Vector2 center, float radius, Color color); // Draw circle outline (Vector version) +void DrawEllipse (int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse +void DrawEllipseLines (int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse outline +void DrawRing (Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring +void DrawRingLines (Vector2 center, float innerRadius, float outerRadius, float startAngle, float endAngle, int segments, Color color); // Draw ring outline +void DrawRectangle (int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle +void DrawRectangleV (Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) +void DrawRectangleRec (Rectangle rec, Color color); // Draw a color-filled rectangle +void DrawRectanglePro (Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters +void DrawRectangleGradientV (int posX, int posY, int width, int height, Color color1, Color color2); // Draw a vertical-gradient-filled rectangle +void DrawRectangleGradientH (int posX, int posY, int width, int height, Color color1, Color color2); // Draw a horizontal-gradient-filled rectangle +void DrawRectangleGradientEx (Rectangle rec, Color col1, Color col2, Color col3, Color col4); // Draw a gradient-filled rectangle with custom vertex colors +void DrawRectangleLines (int posX, int posY, int width, int height, Color color); // Draw rectangle outline +void DrawRectangleLinesEx (Rectangle rec, float lineThick, Color color); // Draw rectangle outline with extended parameters +void DrawRectangleRounded (Rectangle rec, float roundness, int segments, Color color); // Draw rectangle with rounded edges +void DrawRectangleRoundedLines (Rectangle rec, float roundness, int segments, float lineThick, Color color); // Draw rectangle with rounded edges outline +void DrawTriangle (Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) +void DrawTriangleLines (Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline (vertex in counter-clockwise order!) +void DrawTriangleFan (Vector2* points, int pointCount, Color color); // Draw a triangle fan defined by points (first vertex is the center) +void DrawTriangleStrip (Vector2* points, int pointCount, Color color); // Draw a triangle strip defined by points +void DrawPoly (Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version) +void DrawPolyLines (Vector2 center, int sides, float radius, float rotation, Color color); // Draw a polygon outline of n sides +void DrawPolyLinesEx (Vector2 center, int sides, float radius, float rotation, float lineThick, Color color); // Draw a polygon outline of n sides with extended parameters + +// Splines drawing functions +void DrawSplineLinear (Vector2* points, int pointCount, float thick, Color color); // Draw spline: Linear, minimum 2 points +void DrawSplineBasis (Vector2* points, int pointCount, float thick, Color color); // Draw spline: B-Spline, minimum 4 points +void DrawSplineCatmullRom (Vector2* points, int pointCount, float thick, Color color); // Draw spline: Catmull-Rom, minimum 4 points +void DrawSplineBezierQuadratic (Vector2* points, int pointCount, float thick, Color color); // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] +void DrawSplineBezierCubic (Vector2* points, int pointCount, float thick, Color color); // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] +void DrawSplineSegmentLinear (Vector2 p1, Vector2 p2, float thick, Color color); // Draw spline segment: Linear, 2 points +void DrawSplineSegmentBasis (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: B-Spline, 4 points +void DrawSplineSegmentCatmullRom (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float thick, Color color); // Draw spline segment: Catmull-Rom, 4 points +void DrawSplineSegmentBezierQuadratic (Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point +void DrawSplineSegmentBezierCubic (Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points + +// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] +Vector2 GetSplinePointLinear (Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear +Vector2 GetSplinePointBasis (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline +Vector2 GetSplinePointCatmullRom (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom +Vector2 GetSplinePointBezierQuad (Vector2 p1, Vector2 c2, Vector2 p3, float t); // Get (evaluate) spline point: Quadratic Bezier +Vector2 GetSplinePointBezierCubic (Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float t); // Get (evaluate) spline point: Cubic Bezier + +// Basic shapes collision detection functions +bool CheckCollisionRecs (Rectangle rec1, Rectangle rec2); // Check collision between two rectangles +bool CheckCollisionCircles (Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles +bool CheckCollisionCircleRec (Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle +bool CheckCollisionPointRec (Vector2 point, Rectangle rec); // Check if point is inside rectangle +bool CheckCollisionPointCircle (Vector2 point, Vector2 center, float radius); // Check if point is inside circle +bool CheckCollisionPointTriangle (Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle +bool CheckCollisionPointPoly (Vector2 point, Vector2* points, int pointCount); // Check if point is within a polygon described by array of vertices +bool CheckCollisionLines (Vector2 startPos1, Vector2 endPos1, Vector2 startPos2, Vector2 endPos2, Vector2* collisionPoint); // Check the collision between two lines defined by two points each, returns collision point by reference +bool CheckCollisionPointLine (Vector2 point, Vector2 p1, Vector2 p2, int threshold); // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] +Rectangle GetCollisionRec (Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision + +//------------------------------------------------------------------------------------ +// Texture Loading and Drawing Functions (Module: textures) +//------------------------------------------------------------------------------------ + +// Image loading functions +// NOTE: These functions do not require GPU access +Image LoadImage (const(char)* fileName); // Load image from file into CPU memory (RAM) +Image LoadImageRaw (const(char)* fileName, int width, int height, int format, int headerSize); // Load image from RAW file data +Image LoadImageSvg (const(char)* fileNameOrString, int width, int height); // Load image from SVG file data or string with specified size +Image LoadImageAnim (const(char)* fileName, int* frames); // Load image sequence from file (frames appended to image.data) +Image LoadImageFromMemory (const(char)* fileType, const(ubyte)* fileData, int dataSize); // Load image from memory buffer, fileType refers to extension: i.e. '.png' +Image LoadImageFromTexture (Texture2D texture); // Load image from GPU texture data +Image LoadImageFromScreen (); // Load image from screen buffer and (screenshot) +bool IsImageReady (Image image); // Check if an image is ready +void UnloadImage (Image image); // Unload image from CPU memory (RAM) +bool ExportImage (Image image, const(char)* fileName); // Export image data to file, returns true on success +ubyte* ExportImageToMemory (Image image, const(char)* fileType, int* fileSize); // Export image to memory buffer +bool ExportImageAsCode (Image image, const(char)* fileName); // Export image as code file defining an array of bytes, returns true on success + +// Image generation functions +Image GenImageColor (int width, int height, Color color); // Generate image: plain color +Image GenImageGradientLinear (int width, int height, int direction, Color start, Color end); // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient +Image GenImageGradientRadial (int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient +Image GenImageGradientSquare (int width, int height, float density, Color inner, Color outer); // Generate image: square gradient +Image GenImageChecked (int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked +Image GenImageWhiteNoise (int width, int height, float factor); // Generate image: white noise +Image GenImagePerlinNoise (int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise +Image GenImageCellular (int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells +Image GenImageText (int width, int height, const(char)* text); // Generate image: grayscale image from text data + +// Image manipulation functions +Image ImageCopy (Image image); // Create an image duplicate (useful for transformations) +Image ImageFromImage (Image image, Rectangle rec); // Create an image from another image piece +Image ImageText (const(char)* text, int fontSize, Color color); // Create an image from text (default font) +Image ImageTextEx (Font font, const(char)* text, float fontSize, float spacing, Color tint); // Create an image from text (custom sprite font) +void ImageFormat (Image* image, int newFormat); // Convert image data to desired format +void ImageToPOT (Image* image, Color fill); // Convert image to POT (power-of-two) +void ImageCrop (Image* image, Rectangle crop); // Crop an image to a defined rectangle +void ImageAlphaCrop (Image* image, float threshold); // Crop image depending on alpha value +void ImageAlphaClear (Image* image, Color color, float threshold); // Clear alpha channel to desired color +void ImageAlphaMask (Image* image, Image alphaMask); // Apply alpha mask to image +void ImageAlphaPremultiply (Image* image); // Premultiply alpha channel +void ImageBlurGaussian (Image* image, int blurSize); // Apply Gaussian blur using a box blur approximation +void ImageResize (Image* image, int newWidth, int newHeight); // Resize image (Bicubic scaling algorithm) +void ImageResizeNN (Image* image, int newWidth, int newHeight); // Resize image (Nearest-Neighbor scaling algorithm) +void ImageResizeCanvas (Image* image, int newWidth, int newHeight, int offsetX, int offsetY, Color fill); // Resize canvas and fill with color +void ImageMipmaps (Image* image); // Compute all mipmap levels for a provided image +void ImageDither (Image* image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) +void ImageFlipVertical (Image* image); // Flip image vertically +void ImageFlipHorizontal (Image* image); // Flip image horizontally +void ImageRotate (Image* image, int degrees); // Rotate image by input angle in degrees (-359 to 359) +void ImageRotateCW (Image* image); // Rotate image clockwise 90deg +void ImageRotateCCW (Image* image); // Rotate image counter-clockwise 90deg +void ImageColorTint (Image* image, Color color); // Modify image color: tint +void ImageColorInvert (Image* image); // Modify image color: invert +void ImageColorGrayscale (Image* image); // Modify image color: grayscale +void ImageColorContrast (Image* image, float contrast); // Modify image color: contrast (-100 to 100) +void ImageColorBrightness (Image* image, int brightness); // Modify image color: brightness (-255 to 255) +void ImageColorReplace (Image* image, Color color, Color replace); // Modify image color: replace color +Color* LoadImageColors (Image image); // Load color data from image as a Color array (RGBA - 32bit) +Color* LoadImagePalette (Image image, int maxPaletteSize, int* colorCount); // Load colors palette from image as a Color array (RGBA - 32bit) +void UnloadImageColors (Color* colors); // Unload color data loaded with LoadImageColors() +void UnloadImagePalette (Color* colors); // Unload colors palette loaded with LoadImagePalette() +Rectangle GetImageAlphaBorder (Image image, float threshold); // Get image alpha border rectangle +Color GetImageColor (Image image, int x, int y); // Get image pixel color at (x, y) position + +// Image drawing functions +// NOTE: Image software-rendering functions (CPU) +void ImageClearBackground (Image* dst, Color color); // Clear image background with given color +void ImageDrawPixel (Image* dst, int posX, int posY, Color color); // Draw pixel within an image +void ImageDrawPixelV (Image* dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) +void ImageDrawLine (Image* dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image +void ImageDrawLineV (Image* dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version) +void ImageDrawCircle (Image* dst, int centerX, int centerY, int radius, Color color); // Draw a filled circle within an image +void ImageDrawCircleV (Image* dst, Vector2 center, int radius, Color color); // Draw a filled circle within an image (Vector version) +void ImageDrawCircleLines (Image* dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image +void ImageDrawCircleLinesV (Image* dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version) +void ImageDrawRectangle (Image* dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image +void ImageDrawRectangleV (Image* dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version) +void ImageDrawRectangleRec (Image* dst, Rectangle rec, Color color); // Draw rectangle within an image +void ImageDrawRectangleLines (Image* dst, Rectangle rec, int thick, Color color); // Draw rectangle lines within an image +void ImageDraw (Image* dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint); // Draw a source image within a destination image (tint applied to source) +void ImageDrawText (Image* dst, const(char)* text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) within an image (destination) +void ImageDrawTextEx (Image* dst, Font font, const(char)* text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text (custom sprite font) within an image (destination) + +// Texture loading functions +// NOTE: These functions require GPU access +Texture2D LoadTexture (const(char)* fileName); // Load texture from file into GPU memory (VRAM) +Texture2D LoadTextureFromImage (Image image); // Load texture from image data +TextureCubemap LoadTextureCubemap (Image image, int layout); // Load cubemap from image, multiple image cubemap layouts supported +RenderTexture2D LoadRenderTexture (int width, int height); // Load texture for rendering (framebuffer) +bool IsTextureReady (Texture2D texture); // Check if a texture is ready +void UnloadTexture (Texture2D texture); // Unload texture from GPU memory (VRAM) +bool IsRenderTextureReady (RenderTexture2D target); // Check if a render texture is ready +void UnloadRenderTexture (RenderTexture2D target); // Unload render texture from GPU memory (VRAM) +void UpdateTexture (Texture2D texture, const(void)* pixels); // Update GPU texture with new data +void UpdateTextureRec (Texture2D texture, Rectangle rec, const(void)* pixels); // Update GPU texture rectangle with new data + +// Texture configuration functions +void GenTextureMipmaps (Texture2D* texture); // Generate GPU mipmaps for a texture +void SetTextureFilter (Texture2D texture, int filter); // Set texture scaling filter mode +void SetTextureWrap (Texture2D texture, int wrap); // Set texture wrapping mode + +// Texture drawing functions +void DrawTexture (Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D +void DrawTextureV (Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2 +void DrawTextureEx (Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters +void DrawTextureRec (Texture2D texture, Rectangle source, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle +void DrawTexturePro (Texture2D texture, Rectangle source, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters +void DrawTextureNPatch (Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest, Vector2 origin, float rotation, Color tint); // Draws a texture (or part of it) that stretches or shrinks nicely + +// Color/pixel related functions +Color Fade (Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f +int ColorToInt (Color color); // Get hexadecimal value for a Color +Vector4 ColorNormalize (Color color); // Get Color normalized as float [0..1] +Color ColorFromNormalized (Vector4 normalized); // Get Color from normalized values [0..1] +Vector3 ColorToHSV (Color color); // Get HSV values for a Color, hue [0..360], saturation/value [0..1] +Color ColorFromHSV (float hue, float saturation, float value); // Get a Color from HSV values, hue [0..360], saturation/value [0..1] +Color ColorTint (Color color, Color tint); // Get color multiplied with another color +Color ColorBrightness (Color color, float factor); // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f +Color ColorContrast (Color color, float contrast); // Get color with contrast correction, contrast values between -1.0f and 1.0f +Color ColorAlpha (Color color, float alpha); // Get color with alpha applied, alpha goes from 0.0f to 1.0f +Color ColorAlphaBlend (Color dst, Color src, Color tint); // Get src alpha-blended into dst color with tint +Color GetColor (uint hexValue); // Get Color structure from hexadecimal value +Color GetPixelColor (void* srcPtr, int format); // Get Color from a source pixel pointer of certain format +void SetPixelColor (void* dstPtr, Color color, int format); // Set color formatted into destination pixel pointer +int GetPixelDataSize (int width, int height, int format); // Get pixel data size in bytes for certain format + +//------------------------------------------------------------------------------------ +// Font Loading and Text Drawing Functions (Module: text) +//------------------------------------------------------------------------------------ + +// Font loading/unloading functions +Font GetFontDefault (); // Get the default Font +Font LoadFont (const(char)* fileName); // Load font from file into GPU memory (VRAM) +Font LoadFontEx (const(char)* fileName, int fontSize, int* codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set +Font LoadFontFromImage (Image image, Color key, int firstChar); // Load font from Image (XNA style) +Font LoadFontFromMemory (const(char)* fileType, const(ubyte)* fileData, int dataSize, int fontSize, int* codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' +bool IsFontReady (Font font); // Check if a font is ready +GlyphInfo* LoadFontData (const(ubyte)* fileData, int dataSize, int fontSize, int* codepoints, int codepointCount, int type); // Load font data for further use +Image GenImageFontAtlas (const(GlyphInfo)* glyphs, Rectangle** glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info +void UnloadFontData (GlyphInfo* glyphs, int glyphCount); // Unload font chars info data (RAM) +void UnloadFont (Font font); // Unload font from GPU memory (VRAM) +bool ExportFontAsCode (Font font, const(char)* fileName); // Export font as code file, returns true on success + +// Text drawing functions +void DrawFPS (int posX, int posY); // Draw current FPS +void DrawText (const(char)* text, int posX, int posY, int fontSize, Color color); // Draw text (using default font) +void DrawTextEx (Font font, const(char)* text, Vector2 position, float fontSize, float spacing, Color tint); // Draw text using font and additional parameters +void DrawTextPro (Font font, const(char)* text, Vector2 position, Vector2 origin, float rotation, float fontSize, float spacing, Color tint); // Draw text using Font and pro parameters (rotation) +void DrawTextCodepoint (Font font, int codepoint, Vector2 position, float fontSize, Color tint); // Draw one character (codepoint) +void DrawTextCodepoints (Font font, const(int)* codepoints, int codepointCount, Vector2 position, float fontSize, float spacing, Color tint); // Draw multiple character (codepoint) + +// Text font info functions +void SetTextLineSpacing (int spacing); // Set vertical line spacing when drawing with line-breaks +int MeasureText (const(char)* text, int fontSize); // Measure string width for default font +Vector2 MeasureTextEx (Font font, const(char)* text, float fontSize, float spacing); // Measure string size for Font +int GetGlyphIndex (Font font, int codepoint); // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found +GlyphInfo GetGlyphInfo (Font font, int codepoint); // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found +Rectangle GetGlyphAtlasRec (Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found + +// Text codepoints management functions (unicode characters) +char* LoadUTF8 (const(int)* codepoints, int length); // Load UTF-8 text encoded from codepoints array +void UnloadUTF8 (char* text); // Unload UTF-8 text encoded from codepoints array +int* LoadCodepoints (const(char)* text, int* count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter +void UnloadCodepoints (int* codepoints); // Unload codepoints data from memory +int GetCodepointCount (const(char)* text); // Get total number of codepoints in a UTF-8 encoded string +int GetCodepoint (const(char)* text, int* codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +int GetCodepointNext (const(char)* text, int* codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +int GetCodepointPrevious (const(char)* text, int* codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure +const(char)* CodepointToUTF8 (int codepoint, int* utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter) + +// Text strings management functions (no UTF-8 strings, only byte chars) +// NOTE: Some strings allocate memory internally for returned strings, just be careful! +int TextCopy (char* dst, const(char)* src); // Copy one string to another, returns bytes copied +bool TextIsEqual (const(char)* text1, const(char)* text2); // Check if two text string are equal +uint TextLength (const(char)* text); // Get text length, checks for '\0' ending +const(char)* TextFormat (const(char)* text, ...); // Text formatting with variables (sprintf() style) +const(char)* TextSubtext (const(char)* text, int position, int length); // Get a piece of a text string +char* TextReplace (char* text, const(char)* replace, const(char)* by); // Replace text string (WARNING: memory must be freed!) +char* TextInsert (const(char)* text, const(char)* insert, int position); // Insert text in a position (WARNING: memory must be freed!) +const(char)* TextJoin (const(char*)* textList, int count, const(char)* delimiter); // Join text strings with delimiter +const(char*)* TextSplit (const(char)* text, char delimiter, int* count); // Split text into multiple strings +void TextAppend (char* text, const(char)* append, int* position); // Append text at specific position and move cursor! +int TextFindIndex (const(char)* text, const(char)* find); // Find first text occurrence within a string +const(char)* TextToUpper (const(char)* text); // Get upper case version of provided string +const(char)* TextToLower (const(char)* text); // Get lower case version of provided string +const(char)* TextToPascal (const(char)* text); // Get Pascal case notation version of provided string +int TextToInteger (const(char)* text); // Get integer value from text (negative values not supported) + +//------------------------------------------------------------------------------------ +// Basic 3d Shapes Drawing Functions (Module: models) +//------------------------------------------------------------------------------------ + +// Basic geometric 3D shapes drawing functions +void DrawLine3D (Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space +void DrawPoint3D (Vector3 position, Color color); // Draw a point in 3D space, actually a small line +void DrawCircle3D (Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space +void DrawTriangle3D (Vector3 v1, Vector3 v2, Vector3 v3, Color color); // Draw a color-filled triangle (vertex in counter-clockwise order!) +void DrawTriangleStrip3D (Vector3* points, int pointCount, Color color); // Draw a triangle strip defined by points +void DrawCube (Vector3 position, float width, float height, float length, Color color); // Draw cube +void DrawCubeV (Vector3 position, Vector3 size, Color color); // Draw cube (Vector version) +void DrawCubeWires (Vector3 position, float width, float height, float length, Color color); // Draw cube wires +void DrawCubeWiresV (Vector3 position, Vector3 size, Color color); // Draw cube wires (Vector version) +void DrawSphere (Vector3 centerPos, float radius, Color color); // Draw sphere +void DrawSphereEx (Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters +void DrawSphereWires (Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires +void DrawCylinder (Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone +void DrawCylinderEx (Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder with base at startPos and top at endPos +void DrawCylinderWires (Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires +void DrawCylinderWiresEx (Vector3 startPos, Vector3 endPos, float startRadius, float endRadius, int sides, Color color); // Draw a cylinder wires with base at startPos and top at endPos +void DrawCapsule (Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw a capsule with the center of its sphere caps at startPos and endPos +void DrawCapsuleWires (Vector3 startPos, Vector3 endPos, float radius, int slices, int rings, Color color); // Draw capsule wireframe with the center of its sphere caps at startPos and endPos +void DrawPlane (Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ +void DrawRay (Ray ray, Color color); // Draw a ray line +void DrawGrid (int slices, float spacing); // Draw a grid (centered at (0, 0, 0)) + +//------------------------------------------------------------------------------------ +// Model 3d Loading and Drawing Functions (Module: models) +//------------------------------------------------------------------------------------ + +// Model management functions +Model LoadModel (const(char)* fileName); // Load model from files (meshes and materials) +Model LoadModelFromMesh (Mesh mesh); // Load model from generated mesh (default material) +bool IsModelReady (Model model); // Check if a model is ready +void UnloadModel (Model model); // Unload model (including meshes) from memory (RAM and/or VRAM) +BoundingBox GetModelBoundingBox (Model model); // Compute model bounding box limits (considers all meshes) + +// Model drawing functions +void DrawModel (Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set) +void DrawModelEx (Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters +void DrawModelWires (Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set) +void DrawModelWiresEx (Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters +void DrawBoundingBox (BoundingBox box, Color color); // Draw bounding box (wires) +void DrawBillboard (Camera camera, Texture2D texture, Vector3 position, float size, Color tint); // Draw a billboard texture +void DrawBillboardRec (Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector2 size, Color tint); // Draw a billboard texture defined by source +void DrawBillboardPro (Camera camera, Texture2D texture, Rectangle source, Vector3 position, Vector3 up, Vector2 size, Vector2 origin, float rotation, Color tint); // Draw a billboard texture defined by source and rotation + +// Mesh management functions +void UploadMesh (Mesh* mesh, bool dynamic); // Upload mesh vertex data in GPU and provide VAO/VBO ids +void UpdateMeshBuffer (Mesh mesh, int index, const(void)* data, int dataSize, int offset); // Update mesh vertex data in GPU for a specific buffer index +void UnloadMesh (Mesh mesh); // Unload mesh data from CPU and GPU +void DrawMesh (Mesh mesh, Material material, Matrix transform); // Draw a 3d mesh with material and transform +void DrawMeshInstanced (Mesh mesh, Material material, const(Matrix)* transforms, int instances); // Draw multiple mesh instances with material and different transforms +bool ExportMesh (Mesh mesh, const(char)* fileName); // Export mesh data to file, returns true on success +BoundingBox GetMeshBoundingBox (Mesh mesh); // Compute mesh bounding box limits +void GenMeshTangents (Mesh* mesh); // Compute mesh tangents + +// Mesh generation functions +Mesh GenMeshPoly (int sides, float radius); // Generate polygonal mesh +Mesh GenMeshPlane (float width, float length, int resX, int resZ); // Generate plane mesh (with subdivisions) +Mesh GenMeshCube (float width, float height, float length); // Generate cuboid mesh +Mesh GenMeshSphere (float radius, int rings, int slices); // Generate sphere mesh (standard sphere) +Mesh GenMeshHemiSphere (float radius, int rings, int slices); // Generate half-sphere mesh (no bottom cap) +Mesh GenMeshCylinder (float radius, float height, int slices); // Generate cylinder mesh +Mesh GenMeshCone (float radius, float height, int slices); // Generate cone/pyramid mesh +Mesh GenMeshTorus (float radius, float size, int radSeg, int sides); // Generate torus mesh +Mesh GenMeshKnot (float radius, float size, int radSeg, int sides); // Generate trefoil knot mesh +Mesh GenMeshHeightmap (Image heightmap, Vector3 size); // Generate heightmap mesh from image data +Mesh GenMeshCubicmap (Image cubicmap, Vector3 cubeSize); // Generate cubes-based map mesh from image data + +// Material loading/unloading functions +Material* LoadMaterials (const(char)* fileName, int* materialCount); // Load materials from model file +Material LoadMaterialDefault (); // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) +bool IsMaterialReady (Material material); // Check if a material is ready +void UnloadMaterial (Material material); // Unload material from GPU memory (VRAM) +void SetMaterialTexture (Material* material, int mapType, Texture2D texture); // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) +void SetModelMeshMaterial (Model* model, int meshId, int materialId); // Set material for a mesh + +// Model animations loading/unloading functions +ModelAnimation* LoadModelAnimations (const(char)* fileName, int* animCount); // Load model animations from file +void UpdateModelAnimation (Model model, ModelAnimation anim, int frame); // Update model animation pose +void UnloadModelAnimation (ModelAnimation anim); // Unload animation data +void UnloadModelAnimations (ModelAnimation* animations, int animCount); // Unload animation array data +bool IsModelAnimationValid (Model model, ModelAnimation anim); // Check model animation skeleton match + +// Collision detection functions +bool CheckCollisionSpheres (Vector3 center1, float radius1, Vector3 center2, float radius2); // Check collision between two spheres +bool CheckCollisionBoxes (BoundingBox box1, BoundingBox box2); // Check collision between two bounding boxes +bool CheckCollisionBoxSphere (BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere +RayCollision GetRayCollisionSphere (Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere +RayCollision GetRayCollisionBox (Ray ray, BoundingBox box); // Get collision info between ray and box +RayCollision GetRayCollisionMesh (Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh +RayCollision GetRayCollisionTriangle (Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle +RayCollision GetRayCollisionQuad (Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad + +//------------------------------------------------------------------------------------ +// Audio Loading and Playing Functions (Module: audio) +//------------------------------------------------------------------------------------ +alias AudioCallback = void function (void* bufferData, uint frames); + +// Audio device management functions +void InitAudioDevice (); // Initialize audio device and context +void CloseAudioDevice (); // Close the audio device and context +bool IsAudioDeviceReady (); // Check if audio device has been initialized successfully +void SetMasterVolume (float volume); // Set master volume (listener) +float GetMasterVolume (); // Get master volume (listener) + +// Wave/Sound loading/unloading functions +Wave LoadWave (const(char)* fileName); // Load wave data from file +Wave LoadWaveFromMemory (const(char)* fileType, const(ubyte)* fileData, int dataSize); // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' +bool IsWaveReady (Wave wave); // Checks if wave data is ready +Sound LoadSound (const(char)* fileName); // Load sound from file +Sound LoadSoundFromWave (Wave wave); // Load sound from wave data +Sound LoadSoundAlias (Sound source); // Create a new sound that shares the same sample data as the source sound, does not own the sound data +bool IsSoundReady (Sound sound); // Checks if a sound is ready +void UpdateSound (Sound sound, const(void)* data, int sampleCount); // Update sound buffer with new data +void UnloadWave (Wave wave); // Unload wave data +void UnloadSound (Sound sound); // Unload sound +void UnloadSoundAlias (Sound alias_); // Unload a sound alias (does not deallocate sample data) +bool ExportWave (Wave wave, const(char)* fileName); // Export wave data to file, returns true on success +bool ExportWaveAsCode (Wave wave, const(char)* fileName); // Export wave sample data to code (.h), returns true on success + +// Wave/Sound management functions +void PlaySound (Sound sound); // Play a sound +void StopSound (Sound sound); // Stop playing a sound +void PauseSound (Sound sound); // Pause a sound +void ResumeSound (Sound sound); // Resume a paused sound +bool IsSoundPlaying (Sound sound); // Check if a sound is currently playing +void SetSoundVolume (Sound sound, float volume); // Set volume for a sound (1.0 is max level) +void SetSoundPitch (Sound sound, float pitch); // Set pitch for a sound (1.0 is base level) +void SetSoundPan (Sound sound, float pan); // Set pan for a sound (0.5 is center) +Wave WaveCopy (Wave wave); // Copy a wave to a new wave +void WaveCrop (Wave* wave, int initSample, int finalSample); // Crop a wave to defined samples range +void WaveFormat (Wave* wave, int sampleRate, int sampleSize, int channels); // Convert wave data to desired format +float* LoadWaveSamples (Wave wave); // Load samples data from wave as a 32bit float data array +void UnloadWaveSamples (float* samples); // Unload samples data loaded with LoadWaveSamples() + +// Music management functions +Music LoadMusicStream (const(char)* fileName); // Load music stream from file +Music LoadMusicStreamFromMemory (const(char)* fileType, const(ubyte)* data, int dataSize); // Load music stream from data +bool IsMusicReady (Music music); // Checks if a music stream is ready +void UnloadMusicStream (Music music); // Unload music stream +void PlayMusicStream (Music music); // Start music playing +bool IsMusicStreamPlaying (Music music); // Check if music is playing +void UpdateMusicStream (Music music); // Updates buffers for music streaming +void StopMusicStream (Music music); // Stop music playing +void PauseMusicStream (Music music); // Pause music playing +void ResumeMusicStream (Music music); // Resume playing paused music +void SeekMusicStream (Music music, float position); // Seek music to a position (in seconds) +void SetMusicVolume (Music music, float volume); // Set volume for music (1.0 is max level) +void SetMusicPitch (Music music, float pitch); // Set pitch for a music (1.0 is base level) +void SetMusicPan (Music music, float pan); // Set pan for a music (0.5 is center) +float GetMusicTimeLength (Music music); // Get music time length (in seconds) +float GetMusicTimePlayed (Music music); // Get current music time played (in seconds) + +// AudioStream management functions +AudioStream LoadAudioStream (uint sampleRate, uint sampleSize, uint channels); // Load audio stream (to stream raw audio pcm data) +bool IsAudioStreamReady (AudioStream stream); // Checks if an audio stream is ready +void UnloadAudioStream (AudioStream stream); // Unload audio stream and free memory +void UpdateAudioStream (AudioStream stream, const(void)* data, int frameCount); // Update audio stream buffers with data +bool IsAudioStreamProcessed (AudioStream stream); // Check if any audio stream buffers requires refill +void PlayAudioStream (AudioStream stream); // Play audio stream +void PauseAudioStream (AudioStream stream); // Pause audio stream +void ResumeAudioStream (AudioStream stream); // Resume audio stream +bool IsAudioStreamPlaying (AudioStream stream); // Check if audio stream is playing +void StopAudioStream (AudioStream stream); // Stop audio stream +void SetAudioStreamVolume (AudioStream stream, float volume); // Set volume for audio stream (1.0 is max level) +void SetAudioStreamPitch (AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level) +void SetAudioStreamPan (AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered) +void SetAudioStreamBufferSizeDefault (int size); // Default size for new audio streams +void SetAudioStreamCallback (AudioStream stream, AudioCallback callback); // Audio thread callback to request new data + +void AttachAudioStreamProcessor (AudioStream stream, AudioCallback processor); // Attach audio stream processor to stream, receives the samples as s +void DetachAudioStreamProcessor (AudioStream stream, AudioCallback processor); // Detach audio stream processor from stream + +void AttachAudioMixedProcessor (AudioCallback processor); // Attach audio stream processor to the entire audio pipeline, receives the samples as s +void DetachAudioMixedProcessor (AudioCallback processor); // Detach audio stream processor from the entire audio pipeline + +// RAYLIB_H diff --git a/vendor/ray/raymath.d b/vendor/ray/raymath.d new file mode 100644 index 0000000..ee23c72 --- /dev/null +++ b/vendor/ray/raymath.d @@ -0,0 +1,678 @@ +/********************************************************************************************** +* +* raymath v1.5 - Math functions to work with Vector2, Vector3, Matrix and Quaternions +* +* CONVENTIONS: +* - Matrix structure is defined as row-major (memory layout) but parameters naming AND all +* math operations performed by the library consider the structure as it was column-major +* It is like transposed versions of the matrices are used for all the maths +* It benefits some functions making them cache-friendly and also avoids matrix +* transpositions sometimes required by OpenGL +* Example: In memory order, row0 is [m0 m4 m8 m12] but in semantic math row0 is [m0 m1 m2 m3] +* - Functions are always self-contained, no function use another raymath function inside, +* required code is directly re-implemented inside +* - Functions input parameters are always received by value (2 unavoidable exceptions) +* - Functions use always a "result" variable for return +* - Functions are always defined inline +* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience) +* - No compound literals used to make sure libray is compatible with C++ +* +* CONFIGURATION: +* #define RAYMATH_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RAYMATH_STATIC_INLINE +* Define static inline functions code, so #include header suffices for use. +* This may use up lots of memory. +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2015-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +module popka.vendor.ray.raymath; + +extern (C): + +// Function specifiers definition + +// We are building raylib as a Win32 shared library (.dll). + +// We are using raylib as a Win32 shared library (.dll) + +// Provide external definition + +// Functions may be inlined, no external out-of-line definition + +// plain inline not supported by tinycc (See issue #435) // Functions may be inlined or external definition used + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- + +enum PI = 3.14159265358979323846f; + +enum EPSILON = 0.000001f; + +enum DEG2RAD = PI / 180.0f; + +enum RAD2DEG = 180.0f / PI; + +// Get float vector for Matrix + +extern (D) auto MatrixToFloat(T)(auto ref T mat) +{ + return MatrixToFloatV(mat).v; +} + +// Get float vector for Vector3 + +extern (D) auto Vector3ToFloat(T)(auto ref T vec) +{ + return Vector3ToFloatV(vec).v; +} + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Vector2 type +struct Vector2 +{ + float x; + float y; +} + +// Vector3 type +struct Vector3 +{ + float x; + float y; + float z; +} + +// Vector4 type +struct Vector4 +{ + float x; + float y; + float z; + float w; +} + +// Quaternion type +alias Quaternion = Vector4; + +// Matrix type (OpenGL style 4x4 - right handed, column major) +struct Matrix +{ + float m0; + float m4; + float m8; + float m12; // Matrix first row (4 components) + float m1; + float m5; + float m9; + float m13; // Matrix second row (4 components) + float m2; + float m6; + float m10; + float m14; // Matrix third row (4 components) + float m3; + float m7; + float m11; + float m15; // Matrix fourth row (4 components) +} + +// NOTE: Helper types to be used instead of array return types for *ToFloat functions +struct float3 +{ + float[3] v; +} + +struct float16 +{ + float[16] v; +} + +// Required for: sinf(), cosf(), tan(), atan2f(), sqrtf(), floor(), fminf(), fmaxf(), fabs() + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Utils math +//---------------------------------------------------------------------------------- + +// Clamp float value +float Clamp (float value, float min, float max); + +// Calculate linear interpolation between two floats +float Lerp (float start, float end, float amount); + +// Normalize input value within input range +float Normalize (float value, float start, float end); + +// Remap input value within input range to output range +float Remap ( + float value, + float inputStart, + float inputEnd, + float outputStart, + float outputEnd); + +// Wrap input value from min to max +float Wrap (float value, float min, float max); + +// Check whether two given floats are almost equal +int FloatEquals (float x, float y); + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vector2 math +//---------------------------------------------------------------------------------- + +// Vector with components value 0.0f +Vector2 Vector2Zero (); + +// Vector with components value 1.0f +Vector2 Vector2One (); + +// Add two vectors (v1 + v2) +Vector2 Vector2Add (Vector2 v1, Vector2 v2); + +// Add vector and float value +Vector2 Vector2AddValue (Vector2 v, float add); + +// Subtract two vectors (v1 - v2) +Vector2 Vector2Subtract (Vector2 v1, Vector2 v2); + +// Subtract vector by float value +Vector2 Vector2SubtractValue (Vector2 v, float sub); + +// Calculate vector length +float Vector2Length (Vector2 v); + +// Calculate vector square length +float Vector2LengthSqr (Vector2 v); + +// Calculate two vectors dot product +float Vector2DotProduct (Vector2 v1, Vector2 v2); + +// Calculate distance between two vectors +float Vector2Distance (Vector2 v1, Vector2 v2); + +// Calculate square distance between two vectors +float Vector2DistanceSqr (Vector2 v1, Vector2 v2); + +// Calculate angle between two vectors +// NOTE: Angle is calculated from origin point (0, 0) +float Vector2Angle (Vector2 v1, Vector2 v2); + +// Calculate angle defined by a two vectors line +// NOTE: Parameters need to be normalized +// Current implementation should be aligned with glm::angle + +// TODO(10/9/2023): Currently angles move clockwise, determine if this is wanted behavior +float Vector2LineAngle (Vector2 start, Vector2 end); + +// Scale vector (multiply by value) +Vector2 Vector2Scale (Vector2 v, float scale); + +// Multiply vector by vector +Vector2 Vector2Multiply (Vector2 v1, Vector2 v2); + +// Negate vector +Vector2 Vector2Negate (Vector2 v); + +// Divide vector by vector +Vector2 Vector2Divide (Vector2 v1, Vector2 v2); + +// Normalize provided vector +Vector2 Vector2Normalize (Vector2 v); + +// Transforms a Vector2 by a given Matrix +Vector2 Vector2Transform (Vector2 v, Matrix mat); + +// Calculate linear interpolation between two vectors +Vector2 Vector2Lerp (Vector2 v1, Vector2 v2, float amount); + +// Calculate reflected vector to normal + +// Dot product +Vector2 Vector2Reflect (Vector2 v, Vector2 normal); + +// Rotate vector by angle +Vector2 Vector2Rotate (Vector2 v, float angle); + +// Move Vector towards target +Vector2 Vector2MoveTowards (Vector2 v, Vector2 target, float maxDistance); + +// Invert the given vector +Vector2 Vector2Invert (Vector2 v); + +// Clamp the components of the vector between +// min and max values specified by the given vectors +Vector2 Vector2Clamp (Vector2 v, Vector2 min, Vector2 max); + +// Clamp the magnitude of the vector between two min and max values +Vector2 Vector2ClampValue (Vector2 v, float min, float max); + +// Check whether two given vectors are almost equal +int Vector2Equals (Vector2 p, Vector2 q); + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vector3 math +//---------------------------------------------------------------------------------- + +// Vector with components value 0.0f +Vector3 Vector3Zero (); + +// Vector with components value 1.0f +Vector3 Vector3One (); + +// Add two vectors +Vector3 Vector3Add (Vector3 v1, Vector3 v2); + +// Add vector and float value +Vector3 Vector3AddValue (Vector3 v, float add); + +// Subtract two vectors +Vector3 Vector3Subtract (Vector3 v1, Vector3 v2); + +// Subtract vector by float value +Vector3 Vector3SubtractValue (Vector3 v, float sub); + +// Multiply vector by scalar +Vector3 Vector3Scale (Vector3 v, float scalar); + +// Multiply vector by vector +Vector3 Vector3Multiply (Vector3 v1, Vector3 v2); + +// Calculate two vectors cross product +Vector3 Vector3CrossProduct (Vector3 v1, Vector3 v2); + +// Calculate one vector perpendicular vector + +// Cross product between vectors +Vector3 Vector3Perpendicular (Vector3 v); + +// Calculate vector length +float Vector3Length (const Vector3 v); + +// Calculate vector square length +float Vector3LengthSqr (const Vector3 v); + +// Calculate two vectors dot product +float Vector3DotProduct (Vector3 v1, Vector3 v2); + +// Calculate distance between two vectors +float Vector3Distance (Vector3 v1, Vector3 v2); + +// Calculate square distance between two vectors +float Vector3DistanceSqr (Vector3 v1, Vector3 v2); + +// Calculate angle between two vectors +float Vector3Angle (Vector3 v1, Vector3 v2); + +// Negate provided vector (invert direction) +Vector3 Vector3Negate (Vector3 v); + +// Divide vector by vector +Vector3 Vector3Divide (Vector3 v1, Vector3 v2); + +// Normalize provided vector +Vector3 Vector3Normalize (Vector3 v); + +//Calculate the projection of the vector v1 on to v2 +Vector3 Vector3Project (Vector3 v1, Vector3 v2); + +//Calculate the rejection of the vector v1 on to v2 +Vector3 Vector3Reject (Vector3 v1, Vector3 v2); + +// Orthonormalize provided vectors +// Makes vectors normalized and orthogonal to each other +// Gram-Schmidt function implementation + +// Vector3Normalize(*v1); + +// Vector3CrossProduct(*v1, *v2) + +// Vector3Normalize(vn1); + +// Vector3CrossProduct(vn1, *v1) +void Vector3OrthoNormalize (Vector3* v1, Vector3* v2); + +// Transforms a Vector3 by a given Matrix +Vector3 Vector3Transform (Vector3 v, Matrix mat); + +// Transform a vector by quaternion rotation +Vector3 Vector3RotateByQuaternion (Vector3 v, Quaternion q); + +// Rotates a vector around an axis + +// Using Euler-Rodrigues Formula +// Ref.: https://en.wikipedia.org/w/index.php?title=Euler%E2%80%93Rodrigues_formula + +// Vector3Normalize(axis); + +// Vector3CrossProduct(w, v) + +// Vector3CrossProduct(w, wv) + +// Vector3Scale(wv, 2*a) + +// Vector3Scale(wwv, 2) +Vector3 Vector3RotateByAxisAngle (Vector3 v, Vector3 axis, float angle); + +// Calculate linear interpolation between two vectors +Vector3 Vector3Lerp (Vector3 v1, Vector3 v2, float amount); + +// Calculate reflected vector to normal + +// I is the original vector +// N is the normal of the incident plane +// R = I - (2*N*(DotProduct[I, N])) +Vector3 Vector3Reflect (Vector3 v, Vector3 normal); + +// Get min value for each pair of components +Vector3 Vector3Min (Vector3 v1, Vector3 v2); + +// Get max value for each pair of components +Vector3 Vector3Max (Vector3 v1, Vector3 v2); + +// Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c) +// NOTE: Assumes P is on the plane of the triangle + +// Vector3Subtract(b, a) +// Vector3Subtract(c, a) +// Vector3Subtract(p, a) +// Vector3DotProduct(v0, v0) +// Vector3DotProduct(v0, v1) +// Vector3DotProduct(v1, v1) +// Vector3DotProduct(v2, v0) +// Vector3DotProduct(v2, v1) +Vector3 Vector3Barycenter (Vector3 p, Vector3 a, Vector3 b, Vector3 c); + +// Projects a Vector3 from screen space into object space +// NOTE: We are avoiding calling other raymath functions despite available + +// Calculate unprojected matrix (multiply view matrix by projection matrix) and invert it +// MatrixMultiply(view, projection); + +// Calculate inverted matrix -> MatrixInvert(matViewProj); +// Cache the matrix values (speed optimization) + +// Calculate the invert determinant (inlined to avoid double-caching) + +// Create quaternion from source point + +// Multiply quat point by unprojecte matrix +// QuaternionTransform(quat, matViewProjInv) + +// Normalized world points in vectors +Vector3 Vector3Unproject (Vector3 source, Matrix projection, Matrix view); + +// Get Vector3 as float array +float3 Vector3ToFloatV (Vector3 v); + +// Invert the given vector +Vector3 Vector3Invert (Vector3 v); + +// Clamp the components of the vector between +// min and max values specified by the given vectors +Vector3 Vector3Clamp (Vector3 v, Vector3 min, Vector3 max); + +// Clamp the magnitude of the vector between two values +Vector3 Vector3ClampValue (Vector3 v, float min, float max); + +// Check whether two given vectors are almost equal +int Vector3Equals (Vector3 p, Vector3 q); + +// Compute the direction of a refracted ray +// v: normalized direction of the incoming ray +// n: normalized normal vector of the interface of two optical media +// r: ratio of the refractive index of the medium from where the ray comes +// to the refractive index of the medium on the other side of the surface +Vector3 Vector3Refract (Vector3 v, Vector3 n, float r); + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Matrix math +//---------------------------------------------------------------------------------- + +// Compute matrix determinant + +// Cache the matrix values (speed optimization) +float MatrixDeterminant (Matrix mat); + +// Get the trace of the matrix (sum of the values along the diagonal) +float MatrixTrace (Matrix mat); + +// Transposes provided matrix +Matrix MatrixTranspose (Matrix mat); + +// Invert provided matrix + +// Cache the matrix values (speed optimization) + +// Calculate the invert determinant (inlined to avoid double-caching) +Matrix MatrixInvert (Matrix mat); + +// Get identity matrix +Matrix MatrixIdentity (); + +// Add two matrices +Matrix MatrixAdd (Matrix left, Matrix right); + +// Subtract two matrices (left - right) +Matrix MatrixSubtract (Matrix left, Matrix right); + +// Get two matrix multiplication +// NOTE: When multiplying matrices... the order matters! +Matrix MatrixMultiply (Matrix left, Matrix right); + +// Get translation matrix +Matrix MatrixTranslate (float x, float y, float z); + +// Create rotation matrix from axis and angle +// NOTE: Angle should be provided in radians +Matrix MatrixRotate (Vector3 axis, float angle); + +// Get x-rotation matrix +// NOTE: Angle must be provided in radians + +// MatrixIdentity() +Matrix MatrixRotateX (float angle); + +// Get y-rotation matrix +// NOTE: Angle must be provided in radians + +// MatrixIdentity() +Matrix MatrixRotateY (float angle); + +// Get z-rotation matrix +// NOTE: Angle must be provided in radians + +// MatrixIdentity() +Matrix MatrixRotateZ (float angle); + +// Get xyz-rotation matrix +// NOTE: Angle must be provided in radians + +// MatrixIdentity() +Matrix MatrixRotateXYZ (Vector3 angle); + +// Get zyx-rotation matrix +// NOTE: Angle must be provided in radians +Matrix MatrixRotateZYX (Vector3 angle); + +// Get scaling matrix +Matrix MatrixScale (float x, float y, float z); + +// Get perspective projection matrix +Matrix MatrixFrustum ( + double left, + double right, + double bottom, + double top, + double near, + double far); + +// Get perspective projection matrix +// NOTE: Fovy angle must be provided in radians + +// MatrixFrustum(-right, right, -top, top, near, far); +Matrix MatrixPerspective ( + double fovY, + double aspect, + double nearPlane, + double farPlane); + +// Get orthographic projection matrix +Matrix MatrixOrtho ( + double left, + double right, + double bottom, + double top, + double nearPlane, + double farPlane); + +// Get camera look-at matrix (view matrix) + +// Vector3Subtract(eye, target) + +// Vector3Normalize(vz) + +// Vector3CrossProduct(up, vz) + +// Vector3Normalize(x) + +// Vector3CrossProduct(vz, vx) + +// Vector3DotProduct(vx, eye) +// Vector3DotProduct(vy, eye) +// Vector3DotProduct(vz, eye) +Matrix MatrixLookAt (Vector3 eye, Vector3 target, Vector3 up); + +// Get float array of matrix data +float16 MatrixToFloatV (Matrix mat); + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Quaternion math +//---------------------------------------------------------------------------------- + +// Add two quaternions +Quaternion QuaternionAdd (Quaternion q1, Quaternion q2); + +// Add quaternion and float value +Quaternion QuaternionAddValue (Quaternion q, float add); + +// Subtract two quaternions +Quaternion QuaternionSubtract (Quaternion q1, Quaternion q2); + +// Subtract quaternion and float value +Quaternion QuaternionSubtractValue (Quaternion q, float sub); + +// Get identity quaternion +Quaternion QuaternionIdentity (); + +// Computes the length of a quaternion +float QuaternionLength (Quaternion q); + +// Normalize provided quaternion +Quaternion QuaternionNormalize (Quaternion q); + +// Invert provided quaternion +Quaternion QuaternionInvert (Quaternion q); + +// Calculate two quaternion multiplication +Quaternion QuaternionMultiply (Quaternion q1, Quaternion q2); + +// Scale quaternion by float value +Quaternion QuaternionScale (Quaternion q, float mul); + +// Divide two quaternions +Quaternion QuaternionDivide (Quaternion q1, Quaternion q2); + +// Calculate linear interpolation between two quaternions +Quaternion QuaternionLerp (Quaternion q1, Quaternion q2, float amount); + +// Calculate slerp-optimized interpolation between two quaternions + +// QuaternionLerp(q1, q2, amount) + +// QuaternionNormalize(q); +Quaternion QuaternionNlerp (Quaternion q1, Quaternion q2, float amount); + +// Calculates spherical linear interpolation between two quaternions +Quaternion QuaternionSlerp (Quaternion q1, Quaternion q2, float amount); + +// Calculate quaternion based on the rotation from one vector to another + +// Vector3DotProduct(from, to) +// Vector3CrossProduct(from, to) + +// QuaternionNormalize(q); +// NOTE: Normalize to essentially nlerp the original and identity to 0.5 +Quaternion QuaternionFromVector3ToVector3 (Vector3 from, Vector3 to); + +// Get a quaternion for a given rotation matrix +Quaternion QuaternionFromMatrix (Matrix mat); + +// Get a matrix for a given quaternion + +// MatrixIdentity() +Matrix QuaternionToMatrix (Quaternion q); + +// Get rotation quaternion for an angle and axis +// NOTE: Angle must be provided in radians + +// Vector3Normalize(axis) + +// QuaternionNormalize(q); +Quaternion QuaternionFromAxisAngle (Vector3 axis, float angle); + +// Get the rotation angle and axis for a given quaternion + +// QuaternionNormalize(q); + +// This occurs when the angle is zero. +// Not a problem: just set an arbitrary normalized axis. +void QuaternionToAxisAngle (Quaternion q, Vector3* outAxis, float* outAngle); + +// Get the quaternion equivalent to Euler angles +// NOTE: Rotation order is ZYX +Quaternion QuaternionFromEuler (float pitch, float yaw, float roll); + +// Get the Euler angles equivalent to quaternion (roll, pitch, yaw) +// NOTE: Angles are returned in a Vector3 struct in radians + +// Roll (x-axis rotation) + +// Pitch (y-axis rotation) + +// Yaw (z-axis rotation) +Vector3 QuaternionToEuler (Quaternion q); + +// Transform a quaternion given a transformation matrix +Quaternion QuaternionTransform (Quaternion q, Matrix mat); + +// Check whether two given quaternions are almost equal +int QuaternionEquals (Quaternion p, Quaternion q); + +// RAYMATH_H diff --git a/vendor/ray/rlgl.d b/vendor/ray/rlgl.d new file mode 100644 index 0000000..ca26abb --- /dev/null +++ b/vendor/ray/rlgl.d @@ -0,0 +1,2052 @@ +/********************************************************************************************** +* +* rlgl v4.5 - A multi-OpenGL abstraction layer with an immediate-mode style API +* +* DESCRIPTION: +* An abstraction layer for multiple OpenGL versions (1.1, 2.1, 3.3 Core, 4.3 Core, ES 2.0) +* that provides a pseudo-OpenGL 1.1 immediate-mode style API (rlVertex, rlTranslate, rlRotate...) +* +* ADDITIONAL NOTES: +* When choosing an OpenGL backend different than OpenGL 1.1, some internal buffer are +* initialized on rlglInit() to accumulate vertex data. +* +* When an internal state change is required all the stored vertex data is renderer in batch, +* additionally, rlDrawRenderBatchActive() could be called to force flushing of the batch. +* +* Some resources are also loaded for convenience, here the complete list: +* - Default batch (RLGL.defaultBatch): RenderBatch system to accumulate vertex data +* - Default texture (RLGL.defaultTextureId): 1x1 white pixel R8G8B8A8 +* - Default shader (RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs) +* +* Internal buffer (and resources) must be manually unloaded calling rlglClose(). +* +* CONFIGURATION: +* #define GRAPHICS_API_OPENGL_11 +* #define GRAPHICS_API_OPENGL_21 +* #define GRAPHICS_API_OPENGL_33 +* #define GRAPHICS_API_OPENGL_43 +* #define GRAPHICS_API_OPENGL_ES2 +* #define GRAPHICS_API_OPENGL_ES3 +* Use selected OpenGL graphics backend, should be supported by platform +* Those preprocessor defines are only used on rlgl module, if OpenGL version is +* required by any other module, use rlGetVersion() to check it +* +* #define RLGL_IMPLEMENTATION +* Generates the implementation of the library into the included file. +* If not defined, the library is in header only mode and can be included in other headers +* or source files without problems. But only ONE file should hold the implementation. +* +* #define RLGL_RENDER_TEXTURES_HINT +* Enable framebuffer objects (fbo) support (enabled by default) +* Some GPUs could not support them despite the OpenGL version +* +* #define RLGL_SHOW_GL_DETAILS_INFO +* Show OpenGL extensions and capabilities detailed logs on init +* +* #define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT +* Enable debug context (only available on OpenGL 4.3) +* +* rlgl capabilities could be customized just defining some internal +* values before library inclusion (default values listed): +* +* #define RL_DEFAULT_BATCH_BUFFER_ELEMENTS 8192 // Default internal render batch elements limits +* #define RL_DEFAULT_BATCH_BUFFERS 1 // Default number of batch buffers (multi-buffering) +* #define RL_DEFAULT_BATCH_DRAWCALLS 256 // Default number of batch draw calls (by state changes: mode, texture) +* #define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS 4 // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) +* +* #define RL_MAX_MATRIX_STACK_SIZE 32 // Maximum size of internal Matrix stack +* #define RL_MAX_SHADER_LOCATIONS 32 // Maximum number of shader locations supported +* #define RL_CULL_DISTANCE_NEAR 0.01 // Default projection matrix near cull distance +* #define RL_CULL_DISTANCE_FAR 1000.0 // Default projection matrix far cull distance +* +* When loading a shader, the following vertex attributes and uniform +* location names are tried to be set automatically: +* +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION "vertexPosition" // Bound by default to shader location: 0 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD "vertexTexCoord" // Bound by default to shader location: 1 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL "vertexNormal" // Bound by default to shader location: 2 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR "vertexColor" // Bound by default to shader location: 3 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT "vertexTangent" // Bound by default to shader location: 4 +* #define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2 "vertexTexCoord2" // Bound by default to shader location: 5 +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP "mvp" // model-view-projection matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW "matView" // view matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION "matProjection" // projection matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL "matModel" // model matrix +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL "matNormal" // normal matrix (transpose(inverse(matModelView)) +* #define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR "colDiffuse" // color diffuse (base tint color, multiplied by texture color) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0 "texture0" // texture0 (texture slot active 0) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1 "texture1" // texture1 (texture slot active 1) +* #define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2 "texture2" // texture2 (texture slot active 2) +* +* DEPENDENCIES: +* - OpenGL libraries (depending on platform and OpenGL version selected) +* - GLAD OpenGL extensions loading library (only for OpenGL 3.3 Core, 4.3 Core) +* +* +* LICENSE: zlib/libpng +* +* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* +* This software is provided "as-is", without any express or implied warranty. In no event +* will the authors be held liable for any damages arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, including commercial +* applications, and to alter it and redistribute it freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not claim that you +* wrote the original software. If you use this software in a product, an acknowledgment +* in the product documentation would be appreciated but is not required. +* +* 2. Altered source versions must be plainly marked as such, and must not be misrepresented +* as being the original software. +* +* 3. This notice may not be removed or altered from any source distribution. +* +**********************************************************************************************/ + +module popka.vendor.ray.rlgl; + +import core.stdc.stdlib; + +extern (C): + +enum RLGL_VERSION = "4.5"; + +// Function specifiers in case library is build/used as a shared library (Windows) +// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll + +// We are building the library as a Win32 shared library (.dll) + +// We are using the library as a Win32 shared library (.dll) + +// Function specifiers definition // Functions defined as 'extern' by default (implicit specifiers) + +// Support TRACELOG macros + +// Allow custom memory allocators + +alias RL_MALLOC = malloc; + +alias RL_CALLOC = calloc; + +alias RL_REALLOC = realloc; + +alias RL_FREE = free; + +// Security check in case no GRAPHICS_API_OPENGL_* defined + +// Security check in case multiple GRAPHICS_API_OPENGL_* defined + +// OpenGL 2.1 uses most of OpenGL 3.3 Core functionality +// WARNING: Specific parts are checked with #if defines + +// OpenGL 4.3 uses OpenGL 3.3 Core functionality + +// OpenGL ES 3.0 uses OpenGL ES 2.0 functionality (and more) + +// Support framebuffer objects by default +// NOTE: Some driver implementation do not support it, despite they should + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- + +// Default internal render batch elements limits + +// This is the maximum amount of elements (quads) per batch +// NOTE: Be careful with text, every letter maps to a quad +enum RL_DEFAULT_BATCH_BUFFER_ELEMENTS = 8192; + +// We reduce memory sizes for embedded systems (RPI and HTML5) +// NOTE: On HTML5 (emscripten) this is allocated on heap, +// by default it's only 16MB!...just take care... + +enum RL_DEFAULT_BATCH_BUFFERS = 1; // Default number of batch buffers (multi-buffering) + +enum RL_DEFAULT_BATCH_DRAWCALLS = 256; // Default number of batch draw calls (by state changes: mode, texture) + +enum RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS = 4; // Maximum number of textures units that can be activated on batch drawing (SetShaderValueTexture()) + +// Internal Matrix stack + +enum RL_MAX_MATRIX_STACK_SIZE = 32; // Maximum size of Matrix stack + +// Shader limits + +enum RL_MAX_SHADER_LOCATIONS = 32; // Maximum number of shader locations supported + +// Projection matrix culling + +enum RL_CULL_DISTANCE_NEAR = 0.01; // Default near cull distance + +enum RL_CULL_DISTANCE_FAR = 1000.0; // Default far cull distance + +// Texture parameters (equivalent to OpenGL defines) +enum RL_TEXTURE_WRAP_S = 0x2802; // GL_TEXTURE_WRAP_S +enum RL_TEXTURE_WRAP_T = 0x2803; // GL_TEXTURE_WRAP_T +enum RL_TEXTURE_MAG_FILTER = 0x2800; // GL_TEXTURE_MAG_FILTER +enum RL_TEXTURE_MIN_FILTER = 0x2801; // GL_TEXTURE_MIN_FILTER + +enum RL_TEXTURE_FILTER_NEAREST = 0x2600; // GL_NEAREST +enum RL_TEXTURE_FILTER_LINEAR = 0x2601; // GL_LINEAR +enum RL_TEXTURE_FILTER_MIP_NEAREST = 0x2700; // GL_NEAREST_MIPMAP_NEAREST +enum RL_TEXTURE_FILTER_NEAREST_MIP_LINEAR = 0x2702; // GL_NEAREST_MIPMAP_LINEAR +enum RL_TEXTURE_FILTER_LINEAR_MIP_NEAREST = 0x2701; // GL_LINEAR_MIPMAP_NEAREST +enum RL_TEXTURE_FILTER_MIP_LINEAR = 0x2703; // GL_LINEAR_MIPMAP_LINEAR +enum RL_TEXTURE_FILTER_ANISOTROPIC = 0x3000; // Anisotropic filter (custom identifier) +enum RL_TEXTURE_MIPMAP_BIAS_RATIO = 0x4000; // Texture mipmap bias, percentage ratio (custom identifier) + +enum RL_TEXTURE_WRAP_REPEAT = 0x2901; // GL_REPEAT +enum RL_TEXTURE_WRAP_CLAMP = 0x812F; // GL_CLAMP_TO_EDGE +enum RL_TEXTURE_WRAP_MIRROR_REPEAT = 0x8370; // GL_MIRRORED_REPEAT +enum RL_TEXTURE_WRAP_MIRROR_CLAMP = 0x8742; // GL_MIRROR_CLAMP_EXT + +// Matrix modes (equivalent to OpenGL) +enum RL_MODELVIEW = 0x1700; // GL_MODELVIEW +enum RL_PROJECTION = 0x1701; // GL_PROJECTION +enum RL_TEXTURE = 0x1702; // GL_TEXTURE + +// Primitive assembly draw modes +enum RL_LINES = 0x0001; // GL_LINES +enum RL_TRIANGLES = 0x0004; // GL_TRIANGLES +enum RL_QUADS = 0x0007; // GL_QUADS + +// GL equivalent data types +enum RL_UNSIGNED_BYTE = 0x1401; // GL_UNSIGNED_BYTE +enum RL_FLOAT = 0x1406; // GL_FLOAT + +// GL buffer usage hint +enum RL_STREAM_DRAW = 0x88E0; // GL_STREAM_DRAW +enum RL_STREAM_READ = 0x88E1; // GL_STREAM_READ +enum RL_STREAM_COPY = 0x88E2; // GL_STREAM_COPY +enum RL_STATIC_DRAW = 0x88E4; // GL_STATIC_DRAW +enum RL_STATIC_READ = 0x88E5; // GL_STATIC_READ +enum RL_STATIC_COPY = 0x88E6; // GL_STATIC_COPY +enum RL_DYNAMIC_DRAW = 0x88E8; // GL_DYNAMIC_DRAW +enum RL_DYNAMIC_READ = 0x88E9; // GL_DYNAMIC_READ +enum RL_DYNAMIC_COPY = 0x88EA; // GL_DYNAMIC_COPY + +// GL Shader type +enum RL_FRAGMENT_SHADER = 0x8B30; // GL_FRAGMENT_SHADER +enum RL_VERTEX_SHADER = 0x8B31; // GL_VERTEX_SHADER +enum RL_COMPUTE_SHADER = 0x91B9; // GL_COMPUTE_SHADER + +// GL blending factors +enum RL_ZERO = 0; // GL_ZERO +enum RL_ONE = 1; // GL_ONE +enum RL_SRC_COLOR = 0x0300; // GL_SRC_COLOR +enum RL_ONE_MINUS_SRC_COLOR = 0x0301; // GL_ONE_MINUS_SRC_COLOR +enum RL_SRC_ALPHA = 0x0302; // GL_SRC_ALPHA +enum RL_ONE_MINUS_SRC_ALPHA = 0x0303; // GL_ONE_MINUS_SRC_ALPHA +enum RL_DST_ALPHA = 0x0304; // GL_DST_ALPHA +enum RL_ONE_MINUS_DST_ALPHA = 0x0305; // GL_ONE_MINUS_DST_ALPHA +enum RL_DST_COLOR = 0x0306; // GL_DST_COLOR +enum RL_ONE_MINUS_DST_COLOR = 0x0307; // GL_ONE_MINUS_DST_COLOR +enum RL_SRC_ALPHA_SATURATE = 0x0308; // GL_SRC_ALPHA_SATURATE +enum RL_CONSTANT_COLOR = 0x8001; // GL_CONSTANT_COLOR +enum RL_ONE_MINUS_CONSTANT_COLOR = 0x8002; // GL_ONE_MINUS_CONSTANT_COLOR +enum RL_CONSTANT_ALPHA = 0x8003; // GL_CONSTANT_ALPHA +enum RL_ONE_MINUS_CONSTANT_ALPHA = 0x8004; // GL_ONE_MINUS_CONSTANT_ALPHA + +// GL blending functions/equations +enum RL_FUNC_ADD = 0x8006; // GL_FUNC_ADD +enum RL_MIN = 0x8007; // GL_MIN +enum RL_MAX = 0x8008; // GL_MAX +enum RL_FUNC_SUBTRACT = 0x800A; // GL_FUNC_SUBTRACT +enum RL_FUNC_REVERSE_SUBTRACT = 0x800B; // GL_FUNC_REVERSE_SUBTRACT +enum RL_BLEND_EQUATION = 0x8009; // GL_BLEND_EQUATION +enum RL_BLEND_EQUATION_RGB = 0x8009; // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) +enum RL_BLEND_EQUATION_ALPHA = 0x883D; // GL_BLEND_EQUATION_ALPHA +enum RL_BLEND_DST_RGB = 0x80C8; // GL_BLEND_DST_RGB +enum RL_BLEND_SRC_RGB = 0x80C9; // GL_BLEND_SRC_RGB +enum RL_BLEND_DST_ALPHA = 0x80CA; // GL_BLEND_DST_ALPHA +enum RL_BLEND_SRC_ALPHA = 0x80CB; // GL_BLEND_SRC_ALPHA +enum RL_BLEND_COLOR = 0x8005; // GL_BLEND_COLOR + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Boolean type + +// Matrix, 4x4 components, column major, OpenGL style, right handed +struct Matrix +{ + float m0; + float m4; + float m8; + float m12; // Matrix first row (4 components) + float m1; + float m5; + float m9; + float m13; // Matrix second row (4 components) + float m2; + float m6; + float m10; + float m14; // Matrix third row (4 components) + float m3; + float m7; + float m11; + float m15; // Matrix fourth row (4 components) +} + +// Dynamic vertex buffers (position + texcoords + colors + indices arrays) +struct rlVertexBuffer +{ + int elementCount; // Number of elements in the buffer (QUADS) + + float* vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + float* texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + ubyte* colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + + uint* indices; // Vertex indices (in case vertex data comes indexed) (6 indices per quad) + + // Vertex indices (in case vertex data comes indexed) (6 indices per quad) + + uint vaoId; // OpenGL Vertex Array Object id + uint[4] vboId; // OpenGL Vertex Buffer Objects id (4 types of vertex data) +} + +// Draw call type +// NOTE: Only texture changes register a new draw, other state-change-related elements are not +// used at this moment (vaoId, shaderId, matrices), raylib just forces a batch draw call if any +// of those state-change happens (this is done in core module) +struct rlDrawCall +{ + int mode; // Drawing mode: LINES, TRIANGLES, QUADS + int vertexCount; // Number of vertex of the draw + int vertexAlignment; // Number of vertex required for index alignment (LINES, TRIANGLES) + //unsigned int vaoId; // Vertex array id to be used on the draw -> Using RLGL.currentBatch->vertexBuffer.vaoId + //unsigned int shaderId; // Shader id to be used on the draw -> Using RLGL.currentShaderId + uint textureId; // Texture id to be used on the draw -> Use to create new draw call if changes + + //Matrix projection; // Projection matrix for this draw -> Using RLGL.projection by default + //Matrix modelview; // Modelview matrix for this draw -> Using RLGL.modelview by default +} + +// rlRenderBatch type +struct rlRenderBatch +{ + int bufferCount; // Number of vertex buffers (multi-buffering support) + int currentBuffer; // Current buffer tracking in case of multi-buffering + rlVertexBuffer* vertexBuffer; // Dynamic buffer(s) for vertex data + + rlDrawCall* draws; // Draw calls array, depends on textureId + int drawCounter; // Draw calls counter + float currentDepth; // Current depth value for next draw +} + +// OpenGL version +enum +{ + RL_OPENGL_11 = 1, // OpenGL 1.1 + RL_OPENGL_21 = 2, // OpenGL 2.1 (GLSL 120) + RL_OPENGL_33 = 3, // OpenGL 3.3 (GLSL 330) + RL_OPENGL_43 = 4, // OpenGL 4.3 (using GLSL 330) + RL_OPENGL_ES_20 = 5, // OpenGL ES 2.0 (GLSL 100) + RL_OPENGL_ES_30 = 6 // OpenGL ES 3.0 (GLSL 300 es) +} + +// Trace log level +// NOTE: Organized by priority level +enum +{ + RL_LOG_ALL = 0, // Display all logs + RL_LOG_TRACE = 1, // Trace logging, intended for internal use only + RL_LOG_DEBUG = 2, // Debug logging, used for internal debugging, it should be disabled on release builds + RL_LOG_INFO = 3, // Info logging, used for program execution info + RL_LOG_WARNING = 4, // Warning logging, used on recoverable failures + RL_LOG_ERROR = 5, // Error logging, used on unrecoverable failures + RL_LOG_FATAL = 6, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + RL_LOG_NONE = 7 // Disable logging +} + +// Texture pixel formats +// NOTE: Support depends on OpenGL version +enum +{ + RL_PIXELFORMAT_UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + RL_PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA = 2, // 8*2 bpp (2 channels) + RL_PIXELFORMAT_UNCOMPRESSED_R5G6B5 = 3, // 16 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8 = 4, // 24 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R5G5B5A1 = 5, // 16 bpp (1 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R4G4B4A4 = 6, // 16 bpp (4 bit alpha) + RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 = 7, // 32 bpp + RL_PIXELFORMAT_UNCOMPRESSED_R32 = 8, // 32 bpp (1 channel - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32 = 9, // 32*3 bpp (3 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R32G32B32A32 = 10, // 32*4 bpp (4 channels - float) + RL_PIXELFORMAT_UNCOMPRESSED_R16 = 11, // 16 bpp (1 channel - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16 = 12, // 16*3 bpp (3 channels - half float) + RL_PIXELFORMAT_UNCOMPRESSED_R16G16B16A16 = 13, // 16*4 bpp (4 channels - half float) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGB = 14, // 4 bpp (no alpha) + RL_PIXELFORMAT_COMPRESSED_DXT1_RGBA = 15, // 4 bpp (1 bit alpha) + RL_PIXELFORMAT_COMPRESSED_DXT3_RGBA = 16, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_DXT5_RGBA = 17, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ETC1_RGB = 18, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_RGB = 19, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA = 20, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGB = 21, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_PVRT_RGBA = 22, // 4 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA = 23, // 8 bpp + RL_PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA = 24 // 2 bpp +} + +// Texture parameters: filter mode +// NOTE 1: Filtering considers mipmaps if available in the texture +// NOTE 2: Filter is accordingly set for minification and magnification +enum +{ + RL_TEXTURE_FILTER_POINT = 0, // No filter, just pixel approximation + RL_TEXTURE_FILTER_BILINEAR = 1, // Linear filtering + RL_TEXTURE_FILTER_TRILINEAR = 2, // Trilinear filtering (linear with mipmaps) + RL_TEXTURE_FILTER_ANISOTROPIC_4X = 3, // Anisotropic filtering 4x + RL_TEXTURE_FILTER_ANISOTROPIC_8X = 4, // Anisotropic filtering 8x + RL_TEXTURE_FILTER_ANISOTROPIC_16X = 5 // Anisotropic filtering 16x +} + +// Color blending modes (pre-defined) +enum +{ + RL_BLEND_ALPHA = 0, // Blend textures considering alpha (default) + RL_BLEND_ADDITIVE = 1, // Blend textures adding colors + RL_BLEND_MULTIPLIED = 2, // Blend textures multiplying colors + RL_BLEND_ADD_COLORS = 3, // Blend textures adding colors (alternative) + RL_BLEND_SUBTRACT_COLORS = 4, // Blend textures subtracting colors (alternative) + RL_BLEND_ALPHA_PREMULTIPLY = 5, // Blend premultiplied textures considering alpha + RL_BLEND_CUSTOM = 6, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + RL_BLEND_CUSTOM_SEPARATE = 7 // Blend textures using custom src/dst factors (use rlSetBlendFactorsSeparate()) +} + +// Shader location point type +enum +{ + RL_SHADER_LOC_VERTEX_POSITION = 0, // Shader location: vertex attribute: position + RL_SHADER_LOC_VERTEX_TEXCOORD01 = 1, // Shader location: vertex attribute: texcoord01 + RL_SHADER_LOC_VERTEX_TEXCOORD02 = 2, // Shader location: vertex attribute: texcoord02 + RL_SHADER_LOC_VERTEX_NORMAL = 3, // Shader location: vertex attribute: normal + RL_SHADER_LOC_VERTEX_TANGENT = 4, // Shader location: vertex attribute: tangent + RL_SHADER_LOC_VERTEX_COLOR = 5, // Shader location: vertex attribute: color + RL_SHADER_LOC_MATRIX_MVP = 6, // Shader location: matrix uniform: model-view-projection + RL_SHADER_LOC_MATRIX_VIEW = 7, // Shader location: matrix uniform: view (camera transform) + RL_SHADER_LOC_MATRIX_PROJECTION = 8, // Shader location: matrix uniform: projection + RL_SHADER_LOC_MATRIX_MODEL = 9, // Shader location: matrix uniform: model (transform) + RL_SHADER_LOC_MATRIX_NORMAL = 10, // Shader location: matrix uniform: normal + RL_SHADER_LOC_VECTOR_VIEW = 11, // Shader location: vector uniform: view + RL_SHADER_LOC_COLOR_DIFFUSE = 12, // Shader location: vector uniform: diffuse color + RL_SHADER_LOC_COLOR_SPECULAR = 13, // Shader location: vector uniform: specular color + RL_SHADER_LOC_COLOR_AMBIENT = 14, // Shader location: vector uniform: ambient color + RL_SHADER_LOC_MAP_ALBEDO = 15, // Shader location: sampler2d texture: albedo (same as: RL_SHADER_LOC_MAP_DIFFUSE) + RL_SHADER_LOC_MAP_METALNESS = 16, // Shader location: sampler2d texture: metalness (same as: RL_SHADER_LOC_MAP_SPECULAR) + RL_SHADER_LOC_MAP_NORMAL = 17, // Shader location: sampler2d texture: normal + RL_SHADER_LOC_MAP_ROUGHNESS = 18, // Shader location: sampler2d texture: roughness + RL_SHADER_LOC_MAP_OCCLUSION = 19, // Shader location: sampler2d texture: occlusion + RL_SHADER_LOC_MAP_EMISSION = 20, // Shader location: sampler2d texture: emission + RL_SHADER_LOC_MAP_HEIGHT = 21, // Shader location: sampler2d texture: height + RL_SHADER_LOC_MAP_CUBEMAP = 22, // Shader location: samplerCube texture: cubemap + RL_SHADER_LOC_MAP_IRRADIANCE = 23, // Shader location: samplerCube texture: irradiance + RL_SHADER_LOC_MAP_PREFILTER = 24, // Shader location: samplerCube texture: prefilter + RL_SHADER_LOC_MAP_BRDF = 25 // Shader location: sampler2d texture: brdf +} + +enum RL_SHADER_LOC_MAP_DIFFUSE = RL_SHADER_LOC_MAP_ALBEDO; +enum RL_SHADER_LOC_MAP_SPECULAR = RL_SHADER_LOC_MAP_METALNESS; + +// Shader uniform data type +enum +{ + RL_SHADER_UNIFORM_FLOAT = 0, // Shader uniform type: float + RL_SHADER_UNIFORM_VEC2 = 1, // Shader uniform type: vec2 (2 float) + RL_SHADER_UNIFORM_VEC3 = 2, // Shader uniform type: vec3 (3 float) + RL_SHADER_UNIFORM_VEC4 = 3, // Shader uniform type: vec4 (4 float) + RL_SHADER_UNIFORM_INT = 4, // Shader uniform type: int + RL_SHADER_UNIFORM_IVEC2 = 5, // Shader uniform type: ivec2 (2 int) + RL_SHADER_UNIFORM_IVEC3 = 6, // Shader uniform type: ivec3 (3 int) + RL_SHADER_UNIFORM_IVEC4 = 7, // Shader uniform type: ivec4 (4 int) + RL_SHADER_UNIFORM_SAMPLER2D = 8 // Shader uniform type: sampler2d +} + +// Shader attribute data types +enum +{ + RL_SHADER_ATTRIB_FLOAT = 0, // Shader attribute type: float + RL_SHADER_ATTRIB_VEC2 = 1, // Shader attribute type: vec2 (2 float) + RL_SHADER_ATTRIB_VEC3 = 2, // Shader attribute type: vec3 (3 float) + RL_SHADER_ATTRIB_VEC4 = 3 // Shader attribute type: vec4 (4 float) +} + +// Framebuffer attachment type +// NOTE: By default up to 8 color channels defined, but it can be more +enum +{ + RL_ATTACHMENT_COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 + RL_ATTACHMENT_COLOR_CHANNEL1 = 1, // Framebuffer attachment type: color 1 + RL_ATTACHMENT_COLOR_CHANNEL2 = 2, // Framebuffer attachment type: color 2 + RL_ATTACHMENT_COLOR_CHANNEL3 = 3, // Framebuffer attachment type: color 3 + RL_ATTACHMENT_COLOR_CHANNEL4 = 4, // Framebuffer attachment type: color 4 + RL_ATTACHMENT_COLOR_CHANNEL5 = 5, // Framebuffer attachment type: color 5 + RL_ATTACHMENT_COLOR_CHANNEL6 = 6, // Framebuffer attachment type: color 6 + RL_ATTACHMENT_COLOR_CHANNEL7 = 7, // Framebuffer attachment type: color 7 + RL_ATTACHMENT_DEPTH = 100, // Framebuffer attachment type: depth + RL_ATTACHMENT_STENCIL = 200 // Framebuffer attachment type: stencil +} + +// Framebuffer texture attachment type +enum +{ + RL_ATTACHMENT_CUBEMAP_POSITIVE_X = 0, // Framebuffer texture attachment type: cubemap, +X side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_X = 1, // Framebuffer texture attachment type: cubemap, -X side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Y = 2, // Framebuffer texture attachment type: cubemap, +Y side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Y = 3, // Framebuffer texture attachment type: cubemap, -Y side + RL_ATTACHMENT_CUBEMAP_POSITIVE_Z = 4, // Framebuffer texture attachment type: cubemap, +Z side + RL_ATTACHMENT_CUBEMAP_NEGATIVE_Z = 5, // Framebuffer texture attachment type: cubemap, -Z side + RL_ATTACHMENT_TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d + RL_ATTACHMENT_RENDERBUFFER = 200 // Framebuffer texture attachment type: renderbuffer +} + +// Face culling mode +enum +{ + RL_CULL_FACE_FRONT = 0, + RL_CULL_FACE_BACK = 1 +} + +//------------------------------------------------------------------------------------ +// Functions Declaration - Matrix operations +//------------------------------------------------------------------------------------ + +// Prevents name mangling of functions + +void rlMatrixMode (int mode); // Choose the current matrix to be transformed +void rlPushMatrix (); // Push the current matrix to stack +void rlPopMatrix (); // Pop latest inserted matrix from stack +void rlLoadIdentity (); // Reset current matrix to identity matrix +void rlTranslatef (float x, float y, float z); // Multiply the current matrix by a translation matrix +void rlRotatef (float angle, float x, float y, float z); // Multiply the current matrix by a rotation matrix +void rlScalef (float x, float y, float z); // Multiply the current matrix by a scaling matrix +void rlMultMatrixf (const(float)* matf); // Multiply the current matrix by another matrix +void rlFrustum (double left, double right, double bottom, double top, double znear, double zfar); +void rlOrtho (double left, double right, double bottom, double top, double znear, double zfar); +void rlViewport (int x, int y, int width, int height); // Set the viewport area + +//------------------------------------------------------------------------------------ +// Functions Declaration - Vertex level operations +//------------------------------------------------------------------------------------ +void rlBegin (int mode); // Initialize drawing mode (how to organize vertex) +void rlEnd (); // Finish vertex providing +void rlVertex2i (int x, int y); // Define one vertex (position) - 2 int +void rlVertex2f (float x, float y); // Define one vertex (position) - 2 float +void rlVertex3f (float x, float y, float z); // Define one vertex (position) - 3 float +void rlTexCoord2f (float x, float y); // Define one vertex (texture coordinate) - 2 float +void rlNormal3f (float x, float y, float z); // Define one vertex (normal) - 3 float +void rlColor4ub (ubyte r, ubyte g, ubyte b, ubyte a); // Define one vertex (color) - 4 byte +void rlColor3f (float x, float y, float z); // Define one vertex (color) - 3 float +void rlColor4f (float x, float y, float z, float w); // Define one vertex (color) - 4 float + +//------------------------------------------------------------------------------------ +// Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2) +// NOTE: This functions are used to completely abstract raylib code from OpenGL layer, +// some of them are direct wrappers over OpenGL calls, some others are custom +//------------------------------------------------------------------------------------ + +// Vertex buffers state +bool rlEnableVertexArray (uint vaoId); // Enable vertex array (VAO, if supported) +void rlDisableVertexArray (); // Disable vertex array (VAO, if supported) +void rlEnableVertexBuffer (uint id); // Enable vertex buffer (VBO) +void rlDisableVertexBuffer (); // Disable vertex buffer (VBO) +void rlEnableVertexBufferElement (uint id); // Enable vertex buffer element (VBO element) +void rlDisableVertexBufferElement (); // Disable vertex buffer element (VBO element) +void rlEnableVertexAttribute (uint index); // Enable vertex attribute index +void rlDisableVertexAttribute (uint index); // Disable vertex attribute index + +// Enable attribute state pointer +// Disable attribute state pointer + +// Textures state +void rlActiveTextureSlot (int slot); // Select and active a texture slot +void rlEnableTexture (uint id); // Enable texture +void rlDisableTexture (); // Disable texture +void rlEnableTextureCubemap (uint id); // Enable texture cubemap +void rlDisableTextureCubemap (); // Disable texture cubemap +void rlTextureParameters (uint id, int param, int value); // Set texture parameters (filter, wrap) +void rlCubemapParameters (uint id, int param, int value); // Set cubemap parameters (filter, wrap) + +// Shader state +void rlEnableShader (uint id); // Enable shader program +void rlDisableShader (); // Disable shader program + +// Framebuffer state +void rlEnableFramebuffer (uint id); // Enable render texture (fbo) +void rlDisableFramebuffer (); // Disable render texture (fbo), return to default framebuffer +void rlActiveDrawBuffers (int count); // Activate multiple draw color buffers +void rlBlitFramebuffer (int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight, int bufferMask); // Blit active framebuffer to main framebuffer + +// General render state +void rlEnableColorBlend (); // Enable color blending +void rlDisableColorBlend (); // Disable color blending +void rlEnableDepthTest (); // Enable depth test +void rlDisableDepthTest (); // Disable depth test +void rlEnableDepthMask (); // Enable depth write +void rlDisableDepthMask (); // Disable depth write +void rlEnableBackfaceCulling (); // Enable backface culling +void rlDisableBackfaceCulling (); // Disable backface culling +void rlSetCullFace (int mode); // Set face culling mode +void rlEnableScissorTest (); // Enable scissor test +void rlDisableScissorTest (); // Disable scissor test +void rlScissor (int x, int y, int width, int height); // Scissor test +void rlEnableWireMode (); // Enable wire mode +void rlEnablePointMode (); // Enable point mode +void rlDisableWireMode (); // Disable wire mode ( and point ) maybe rename +void rlSetLineWidth (float width); // Set the line drawing width +float rlGetLineWidth (); // Get the line drawing width +void rlEnableSmoothLines (); // Enable line aliasing +void rlDisableSmoothLines (); // Disable line aliasing +void rlEnableStereoRender (); // Enable stereo rendering +void rlDisableStereoRender (); // Disable stereo rendering +bool rlIsStereoRenderEnabled (); // Check if stereo render is enabled + +void rlClearColor (ubyte r, ubyte g, ubyte b, ubyte a); // Clear color buffer with color +void rlClearScreenBuffers (); // Clear used screen buffers (color and depth) +void rlCheckErrors (); // Check and log OpenGL error codes +void rlSetBlendMode (int mode); // Set blending mode +void rlSetBlendFactors (int glSrcFactor, int glDstFactor, int glEquation); // Set blending mode factor and equation (using OpenGL factors) +void rlSetBlendFactorsSeparate (int glSrcRGB, int glDstRGB, int glSrcAlpha, int glDstAlpha, int glEqRGB, int glEqAlpha); // Set blending mode factors and equations separately (using OpenGL factors) + +//------------------------------------------------------------------------------------ +// Functions Declaration - rlgl functionality +//------------------------------------------------------------------------------------ +// rlgl initialization functions +void rlglInit (int width, int height); // Initialize rlgl (buffers, shaders, textures, states) +void rlglClose (); // De-initialize rlgl (buffers, shaders, textures) +void rlLoadExtensions (void* loader); // Load OpenGL extensions (loader function required) +int rlGetVersion (); // Get current OpenGL version +void rlSetFramebufferWidth (int width); // Set current framebuffer width +int rlGetFramebufferWidth (); // Get default framebuffer width +void rlSetFramebufferHeight (int height); // Set current framebuffer height +int rlGetFramebufferHeight (); // Get default framebuffer height + +uint rlGetTextureIdDefault (); // Get default texture id +uint rlGetShaderIdDefault (); // Get default shader id +int* rlGetShaderLocsDefault (); // Get default shader locations + +// Render batch management +// NOTE: rlgl provides a default render batch to behave like OpenGL 1.1 immediate mode +// but this render batch API is exposed in case of custom batches are required +rlRenderBatch rlLoadRenderBatch (int numBuffers, int bufferElements); // Load a render batch system +void rlUnloadRenderBatch (rlRenderBatch batch); // Unload render batch system +void rlDrawRenderBatch (rlRenderBatch* batch); // Draw render batch data (Update->Draw->Reset) +void rlSetRenderBatchActive (rlRenderBatch* batch); // Set the active render batch for rlgl (NULL for default internal) +void rlDrawRenderBatchActive (); // Update and draw internal render batch +bool rlCheckRenderBatchLimit (int vCount); // Check internal buffer overflow for a given number of vertex + +void rlSetTexture (uint id); // Set current texture for render batch and check buffers limits + +//------------------------------------------------------------------------------------------------------------------------ + +// Vertex buffers management +uint rlLoadVertexArray (); // Load vertex array (vao) if supported +uint rlLoadVertexBuffer (const(void)* buffer, int size, bool dynamic); // Load a vertex buffer attribute +uint rlLoadVertexBufferElement (const(void)* buffer, int size, bool dynamic); // Load a new attributes element buffer +void rlUpdateVertexBuffer (uint bufferId, const(void)* data, int dataSize, int offset); // Update GPU buffer with new data +void rlUpdateVertexBufferElements (uint id, const(void)* data, int dataSize, int offset); // Update vertex buffer elements with new data +void rlUnloadVertexArray (uint vaoId); +void rlUnloadVertexBuffer (uint vboId); +void rlSetVertexAttribute (uint index, int compSize, int type, bool normalized, int stride, const(void)* pointer); +void rlSetVertexAttributeDivisor (uint index, int divisor); +void rlSetVertexAttributeDefault (int locIndex, const(void)* value, int attribType, int count); // Set vertex attribute default value +void rlDrawVertexArray (int offset, int count); +void rlDrawVertexArrayElements (int offset, int count, const(void)* buffer); +void rlDrawVertexArrayInstanced (int offset, int count, int instances); +void rlDrawVertexArrayElementsInstanced (int offset, int count, const(void)* buffer, int instances); + +// Textures management +uint rlLoadTexture (const(void)* data, int width, int height, int format, int mipmapCount); // Load texture in GPU +uint rlLoadTextureDepth (int width, int height, bool useRenderBuffer); // Load depth texture/renderbuffer (to be attached to fbo) +uint rlLoadTextureCubemap (const(void)* data, int size, int format); // Load texture cubemap +void rlUpdateTexture (uint id, int offsetX, int offsetY, int width, int height, int format, const(void)* data); // Update GPU texture with new data +void rlGetGlTextureFormats (int format, uint* glInternalFormat, uint* glFormat, uint* glType); // Get OpenGL internal formats +const(char)* rlGetPixelFormatName (uint format); // Get name string for pixel format +void rlUnloadTexture (uint id); // Unload texture from GPU memory +void rlGenTextureMipmaps (uint id, int width, int height, int format, int* mipmaps); // Generate mipmap data for selected texture +void* rlReadTexturePixels (uint id, int width, int height, int format); // Read texture pixel data +ubyte* rlReadScreenPixels (int width, int height); // Read screen pixel data (color buffer) + +// Framebuffer management (fbo) +uint rlLoadFramebuffer (int width, int height); // Load an empty framebuffer +void rlFramebufferAttach (uint fboId, uint texId, int attachType, int texType, int mipLevel); // Attach texture/renderbuffer to a framebuffer +bool rlFramebufferComplete (uint id); // Verify framebuffer is complete +void rlUnloadFramebuffer (uint id); // Delete framebuffer from GPU + +// Shaders management +uint rlLoadShaderCode (const(char)* vsCode, const(char)* fsCode); // Load shader from code strings +uint rlCompileShader (const(char)* shaderCode, int type); // Compile custom shader and return shader id (type: RL_VERTEX_SHADER, RL_FRAGMENT_SHADER, RL_COMPUTE_SHADER) +uint rlLoadShaderProgram (uint vShaderId, uint fShaderId); // Load custom shader program +void rlUnloadShaderProgram (uint id); // Unload shader program +int rlGetLocationUniform (uint shaderId, const(char)* uniformName); // Get shader location uniform +int rlGetLocationAttrib (uint shaderId, const(char)* attribName); // Get shader location attribute +void rlSetUniform (int locIndex, const(void)* value, int uniformType, int count); // Set shader value uniform +void rlSetUniformMatrix (int locIndex, Matrix mat); // Set shader value matrix +void rlSetUniformSampler (int locIndex, uint textureId); // Set shader value sampler +void rlSetShader (uint id, int* locs); // Set shader currently active (id and locations) + +// Compute shader management +uint rlLoadComputeShaderProgram (uint shaderId); // Load compute shader program +void rlComputeShaderDispatch (uint groupX, uint groupY, uint groupZ); // Dispatch compute shader (equivalent to *draw* for graphics pipeline) + +// Shader buffer storage object management (ssbo) +uint rlLoadShaderBuffer (uint size, const(void)* data, int usageHint); // Load shader storage buffer object (SSBO) +void rlUnloadShaderBuffer (uint ssboId); // Unload shader storage buffer object (SSBO) +void rlUpdateShaderBuffer (uint id, const(void)* data, uint dataSize, uint offset); // Update SSBO buffer data +void rlBindShaderBuffer (uint id, uint index); // Bind SSBO buffer +void rlReadShaderBuffer (uint id, void* dest, uint count, uint offset); // Read SSBO buffer data (GPU->CPU) +void rlCopyShaderBuffer (uint destId, uint srcId, uint destOffset, uint srcOffset, uint count); // Copy SSBO data between buffers +uint rlGetShaderBufferSize (uint id); // Get SSBO buffer size + +// Buffer management +void rlBindImageTexture (uint id, uint index, int format, bool readonly); // Bind image texture + +// Matrix state management +Matrix rlGetMatrixModelview (); // Get internal modelview matrix +Matrix rlGetMatrixProjection (); // Get internal projection matrix +Matrix rlGetMatrixTransform (); // Get internal accumulated transform matrix +Matrix rlGetMatrixProjectionStereo (int eye); // Get internal projection matrix for stereo render (selected eye) +Matrix rlGetMatrixViewOffsetStereo (int eye); // Get internal view offset matrix for stereo render (selected eye) +void rlSetMatrixProjection (Matrix proj); // Set a custom projection matrix (replaces internal projection matrix) +void rlSetMatrixModelview (Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix) +void rlSetMatrixProjectionStereo (Matrix right, Matrix left); // Set eyes projection matrices for stereo rendering +void rlSetMatrixViewOffsetStereo (Matrix right, Matrix left); // Set eyes view offsets matrices for stereo rendering + +// Quick and dirty cube/quad buffers load->draw->unload +void rlLoadDrawCube (); // Load and draw a cube +void rlLoadDrawQuad (); // Load and draw a quad + +// RLGL_H + +/*********************************************************************************** +* +* RLGL IMPLEMENTATION +* +************************************************************************************/ + +// OpenGL 1.1 library for OSX +// OpenGL extensions library + +// APIENTRY for OpenGL function pointer declarations is required + +// WINGDIAPI definition. Some Windows OpenGL headers need it + +// OpenGL 1.1 library + +// GLAD extensions loading library, includes OpenGL headers + +// OpenGL ES 3.0 library + +// OpenGL ES 2.0 extensions library + +// NOTE: OpenGL ES 2.0 can be enabled on PLATFORM_DESKTOP, +// in that case, functions are loaded from a custom glad for OpenGL ES 2.0 + +//#include // EGL library -> not required, platform layer +// OpenGL ES 2.0 library +// OpenGL ES 2.0 extensions library + +// It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi +// provided headers (despite being defined in official Khronos GLES2 headers) + +// Required for: malloc(), free() +// Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] +// Required for: sqrtf(), sinf(), cosf(), floor(), log() + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- + +// Default shader vertex attribute names to set location points + +// Bound by default to shader location: 0 + +// Bound by default to shader location: 1 + +// Bound by default to shader location: 2 + +// Bound by default to shader location: 3 + +// Bound by default to shader location: 4 + +// Bound by default to shader location: 5 + +// model-view-projection matrix + +// view matrix + +// projection matrix + +// model matrix + +// normal matrix (transpose(inverse(matModelView)) + +// color diffuse (base tint color, multiplied by texture color) + +// texture0 (texture slot active 0) + +// texture1 (texture slot active 1) + +// texture2 (texture slot active 2) + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- + +// Current render batch +// Default internal render batch + +// Current active render batch vertex counter (generic, used for all batches) +// Current active texture coordinate (added on glVertex*()) +// Current active normal (added on glVertex*()) +// Current active color (added on glVertex*()) + +// Current matrix mode +// Current matrix pointer +// Default modelview matrix +// Default projection matrix +// Transform matrix to be used with rlTranslate, rlRotate, rlScale +// Require transform matrix application to current draw-call vertex (if required) +// Matrix stack for push/pop +// Matrix stack counter + +// Default texture used on shapes/poly drawing (required by shader) +// Active texture ids to be enabled on batch drawing (0 active by default) +// Default vertex shader id (used by default shader program) +// Default fragment shader id (used by default shader program) +// Default shader program id, supports vertex color and diffuse texture +// Default shader locations pointer to be used on rendering +// Current shader id to be used on rendering (by default, defaultShaderId) +// Current shader locations pointer to be used on rendering (by default, defaultShaderLocs) + +// Stereo rendering flag +// VR stereo rendering eyes projection matrices +// VR stereo rendering eyes view offset matrices + +// Blending variables +// Blending mode active +// Blending source factor +// Blending destination factor +// Blending equation +// Blending source RGB factor +// Blending destination RGB factor +// Blending source alpha factor +// Blending destination alpha factor +// Blending equation for RGB +// Blending equation for alpha +// Custom blending factor and equation modification status + +// Current framebuffer width +// Current framebuffer height + +// Renderer state + +// VAO support (OpenGL ES2 could not support VAO extension) (GL_ARB_vertex_array_object) +// Instancing supported (GL_ANGLE_instanced_arrays, GL_EXT_draw_instanced + GL_EXT_instanced_arrays) +// NPOT textures full support (GL_ARB_texture_non_power_of_two, GL_OES_texture_npot) +// Depth textures supported (GL_ARB_depth_texture, GL_OES_depth_texture) +// Depth textures supported WebGL specific (GL_WEBGL_depth_texture) +// float textures support (32 bit per channel) (GL_OES_texture_float) +// half float textures support (16 bit per channel) (GL_OES_texture_half_float) +// DDS texture compression support (GL_EXT_texture_compression_s3tc, GL_WEBGL_compressed_texture_s3tc, GL_WEBKIT_WEBGL_compressed_texture_s3tc) +// ETC1 texture compression support (GL_OES_compressed_ETC1_RGB8_texture, GL_WEBGL_compressed_texture_etc1) +// ETC2/EAC texture compression support (GL_ARB_ES3_compatibility) +// PVR texture compression support (GL_IMG_texture_compression_pvrtc) +// ASTC texture compression support (GL_KHR_texture_compression_astc_hdr, GL_KHR_texture_compression_astc_ldr) +// Clamp mirror wrap mode supported (GL_EXT_texture_mirror_clamp) +// Anisotropic texture filtering support (GL_EXT_texture_filter_anisotropic) +// Compute shaders support (GL_ARB_compute_shader) +// Shader storage buffer object support (GL_ARB_shader_storage_buffer_object) + +// Maximum anisotropy level supported (minimum is 2.0f) +// Maximum bits for depth component + +// Extensions supported flags + +// OpenGL extension functions loader signature (same as GLADloadproc) + +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- + +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// NOTE: VAO functionality is exposed through extensions (OES) + +// NOTE: Instancing functionality could also be available through extension + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- + +// Load default shader +// Unload default shader + +// Get compressed format official GL identifier name +// RLGL_SHOW_GL_DETAILS_INFO +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// Get pixel data size in bytes (image or texture) + +// Auxiliar matrix math functions +// Get identity matrix +// Multiply two matrices + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Matrix operations +//---------------------------------------------------------------------------------- + +// Fallback to OpenGL 1.1 function calls +//--------------------------------------- + +// Choose the current matrix to be transformed + +//else if (mode == RL_TEXTURE) // Not supported + +// Push the current matrix into RLGL.State.stack + +// Pop lattest inserted matrix from RLGL.State.stack + +// Reset current matrix to identity matrix + +// Multiply the current matrix by a translation matrix + +// NOTE: We transpose matrix with multiplication order + +// Multiply the current matrix by a rotation matrix +// NOTE: The provided angle must be in degrees + +// Axis vector (x, y, z) normalization + +// Rotation matrix generation + +// NOTE: We transpose matrix with multiplication order + +// Multiply the current matrix by a scaling matrix + +// NOTE: We transpose matrix with multiplication order + +// Multiply the current matrix by another matrix + +// Matrix creation from array + +// Multiply the current matrix by a perspective matrix generated by parameters + +// Multiply the current matrix by an orthographic matrix generated by parameters + +// NOTE: If left-right and top-botton values are equal it could create a division by zero, +// response to it is platform/compiler dependant + +// Set the viewport area (transformation from normalized device coordinates to window coordinates) +// NOTE: We store current viewport dimensions + +//---------------------------------------------------------------------------------- +// Module Functions Definition - Vertex level operations +//---------------------------------------------------------------------------------- + +// Fallback to OpenGL 1.1 function calls +//--------------------------------------- + +// Initialize drawing mode (how to organize vertex) + +// Draw mode can be RL_LINES, RL_TRIANGLES and RL_QUADS +// NOTE: In all three cases, vertex are accumulated over default internal vertex buffer + +// Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, +// that way, following QUADS drawing will keep aligned with index processing +// It implies adding some extra alignment vertex at the end of the draw, +// those vertex are not processed but they are considered as an additional offset +// for the next set of vertex to be drawn + +// Finish vertex providing + +// NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, +// as well as depth buffer bit-depth (16bit or 24bit or 32bit) +// Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) + +// Define one vertex (position) +// NOTE: Vertex position data is the basic information required for drawing + +// Transform provided vector if required + +// WARNING: We can't break primitives when launching a new batch. +// RL_LINES comes in pairs, RL_TRIANGLES come in groups of 3 vertices and RL_QUADS come in groups of 4 vertices. +// We must check current draw.mode when a new vertex is required and finish the batch only if the draw.mode draw.vertexCount is %2, %3 or %4 + +// Reached the maximum number of vertices for RL_LINES drawing +// Launch a draw call but keep current state for next vertices comming +// NOTE: We add +1 vertex to the check for security + +// Add vertices + +// Add current texcoord + +// WARNING: By default rlVertexBuffer struct does not store normals + +// Add current color + +// Define one vertex (position) + +// Define one vertex (position) + +// Define one vertex (texture coordinate) +// NOTE: Texture coordinates are limited to QUADS only + +// Define one vertex (normal) +// NOTE: Normals limited to TRIANGLES only? + +// Define one vertex (color) + +// Define one vertex (color) + +// Define one vertex (color) + +//-------------------------------------------------------------------------------------- +// Module Functions Definition - OpenGL style functions (common to 1.1, 3.3+, ES2) +//-------------------------------------------------------------------------------------- + +// Set current texture to use + +// NOTE: If quads batch limit is reached, we force a draw call and next batch starts + +// Make sure current RLGL.currentBatch->draws[i].vertexCount is aligned a multiple of 4, +// that way, following QUADS drawing will keep aligned with index processing +// It implies adding some extra alignment vertex at the end of the draw, +// those vertex are not processed but they are considered as an additional offset +// for the next set of vertex to be drawn + +// Select and active a texture slot + +// Enable texture + +// Disable texture + +// Enable texture cubemap + +// Disable texture cubemap + +// Set texture parameters (wrap mode/filter mode) + +// Reset anisotropy filter, in case it was set + +// Set cubemap parameters (wrap mode/filter mode) + +// Reset anisotropy filter, in case it was set + +// Enable shader program + +// Disable shader program + +// Enable rendering to texture (fbo) + +// Disable rendering to texture + +// Blit active framebuffer to main framebuffer + +// Activate multiple draw color buffers +// NOTE: One color buffer is always active by default + +// NOTE: Maximum number of draw buffers supported is implementation dependant, +// it can be queried with glGet*() but it must be at least 8 +//GLint maxDrawBuffers = 0; +//glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + +//---------------------------------------------------------------------------------- +// General render state configuration +//---------------------------------------------------------------------------------- + +// Enable color blending + +// Disable color blending + +// Enable depth test + +// Disable depth test + +// Enable depth write + +// Disable depth write + +// Enable backface culling + +// Disable backface culling + +// Set face culling mode + +// Enable scissor test + +// Disable scissor test + +// Scissor test + +// Enable wire mode + +// NOTE: glPolygonMode() not available on OpenGL ES + +// NOTE: glPolygonMode() not available on OpenGL ES + +// Disable wire mode + +// NOTE: glPolygonMode() not available on OpenGL ES + +// Set the line drawing width + +// Get the line drawing width + +// Enable line aliasing + +// Disable line aliasing + +// Enable stereo rendering + +// Disable stereo rendering + +// Check if stereo render is enabled + +// Clear color buffer with color + +// Color values clamp to 0.0f(0) and 1.0f(255) + +// Clear used screen buffers (color and depth) + +// Clear used buffers: Color and Depth (Depth is used for 3D) +//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // Stencil buffer not used... + +// Check and log OpenGL error codes + +// Set blend mode + +// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactors() + +// NOTE: Using GL blend src/dst factors and GL equation configured with rlSetBlendFactorsSeparate() + +// Set blending mode factor and equation + +// Set blending mode factor and equation separately for RGB and alpha + +//---------------------------------------------------------------------------------- +// Module Functions Definition - OpenGL Debug +//---------------------------------------------------------------------------------- + +// Ignore non-significant error/warning codes (NVidia drivers) +// NOTE: Here there are the details with a sample output: +// - #131169 - Framebuffer detailed info: The driver allocated storage for renderbuffer 2. (severity: low) +// - #131185 - Buffer detailed info: Buffer object 1 (bound to GL_ELEMENT_ARRAY_BUFFER_ARB, usage hint is GL_ENUM_88e4) +// will use VIDEO memory as the source for buffer object operations. (severity: low) +// - #131218 - Program/shader state performance warning: Vertex shader in program 7 is being recompiled based on GL state. (severity: medium) +// - #131204 - Texture state usage warning: The texture object (0) bound to texture image unit 0 does not have +// a defined base level and cannot be used for texture mapping. (severity: low) + +//---------------------------------------------------------------------------------- +// Module Functions Definition - rlgl functionality +//---------------------------------------------------------------------------------- + +// Initialize rlgl: OpenGL extensions, default buffers/shaders/textures, OpenGL states + +// Enable OpenGL debug context if required + +// glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, GL_DEBUG_SEVERITY_HIGH, 0, 0, GL_TRUE); + +// Debug context options: +// - GL_DEBUG_OUTPUT - Faster version but not useful for breakpoints +// - GL_DEBUG_OUTPUT_SYNCHRONUS - Callback is in sync with errors, so a breakpoint can be placed on the callback in order to get a stacktrace for the GL error + +// Init default white texture +// 1 pixel RGBA (4 bytes) + +// Init default Shader (customized for GL 3.3 and ES2) +// Loaded: RLGL.State.defaultShaderId + RLGL.State.defaultShaderLocs + +// Init default vertex arrays buffers + +// Init stack matrices (emulating OpenGL 1.1) + +// Init internal matrices + +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// Initialize OpenGL default states +//---------------------------------------------------------- +// Init state: Depth test +// Type of depth testing to apply +// Disable depth testing for 2D (only used for 3D) + +// Init state: Blending mode +// Color blending function (how colors are mixed) +// Enable color blending (required to work with transparencies) + +// Init state: Culling +// NOTE: All shapes/models triangles are drawn CCW +// Cull the back face (default) +// Front face are defined counter clockwise (default) +// Enable backface culling + +// Init state: Cubemap seamless + +// Seamless cubemaps (not supported on OpenGL ES 2.0) + +// Init state: Color hints (deprecated in OpenGL 3.0+) +// Improve quality of color and texture coordinate interpolation +// Smooth shading between vertex (vertex colors interpolation) + +// Store screen size into global variables + +//---------------------------------------------------------- + +// Init state: Color/Depth buffers clear +// Set clear color (black) +// Set clear depth value (default) +// Clear color and depth buffers (depth buffer required for 3D) + +// Vertex Buffer Object deinitialization (memory free) + +// Unload default shader + +// Unload default texture + +// Load OpenGL extensions +// NOTE: External loader function must be provided + +// Also defined for GRAPHICS_API_OPENGL_21 +// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions) + +// Get number of supported extensions + +// Get supported extensions list +// WARNING: glGetStringi() not available on OpenGL 2.1 + +// Register supported extensions flags +// Optional OpenGL 2.1 extensions + +// Register supported extensions flags +// OpenGL 3.3 extensions supported by default (core) + +// Optional OpenGL 3.3 extensions + +// Texture compression: DXT +// Texture compression: ETC2/EAC + +// GRAPHICS_API_OPENGL_33 + +// Register supported extensions flags +// OpenGL ES 3.0 extensions supported by default (or it should be) + +// TODO: Check for additional OpenGL ES 3.0 supported extensions: +//RLGL.ExtSupported.texCompDXT = true; +//RLGL.ExtSupported.texCompETC1 = true; +//RLGL.ExtSupported.texCompETC2 = true; +//RLGL.ExtSupported.texCompPVRT = true; +//RLGL.ExtSupported.texCompASTC = true; +//RLGL.ExtSupported.maxAnisotropyLevel = true; +//RLGL.ExtSupported.computeShader = true; +//RLGL.ExtSupported.ssbo = true; + +// TODO: Support GLAD loader for OpenGL ES 3.0 + +// Get supported extensions list + +// Allocate 512 strings pointers (2 KB) +// One big const string + +// NOTE: We have to duplicate string because glGetString() returns a const string +// Get extensions string size in bytes + +// Check required extensions + +// Check VAO support +// NOTE: Only check on OpenGL ES, OpenGL 3.3 has VAO support as core feature + +// The extension is supported by our hardware and driver, try to get related functions pointers +// NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance... + +//glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)loader("glIsVertexArrayOES"); // NOTE: Fails in WebGL, omitted + +// Check instanced rendering support +// Web ANGLE + +// Standard EXT + +// Check NPOT textures support +// NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature + +// Check texture float support + +// Check depth texture support + +// WebGL requires unsized internal format + +// Not available on WebGL +// Not available on WebGL + +// Check texture compression support: DXT + +// Check texture compression support: ETC1 + +// Check texture compression support: ETC2/EAC + +// Check texture compression support: PVR + +// Check texture compression support: ASTC + +// Check anisotropic texture filter support + +// Check clamp mirror wrap mode support + +// Free extensions pointers + +// Duplicated string must be deallocated +// GRAPHICS_API_OPENGL_ES2 + +// Check OpenGL information and capabilities +//------------------------------------------------------------------------------ +// Show current OpenGL and GLSL version + +// NOTE: Anisotropy levels capability is an extension + +// Show some OpenGL GPU capabilities + +// GRAPHICS_API_OPENGL_43 +// RLGL_SHOW_GL_DETAILS_INFO + +// Show some basic info about GL supported features + +// RLGL_SHOW_GL_DETAILS_INFO + +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// Get current OpenGL version + +// Set current framebuffer width + +// Set current framebuffer height + +// Get default framebuffer width + +// Get default framebuffer height + +// Get default internal texture (white texture) +// NOTE: Default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8 + +// Get default shader id + +// Get default shader locs + +// Render batch management +//------------------------------------------------------------------------------------------------ +// Load render batch + +// Initialize CPU (RAM) vertex buffers (position, texcoord, color data and indexes) +//-------------------------------------------------------------------------------------------- + +// 3 float by vertex, 4 vertex by quad +// 2 float by texcoord, 4 texcoord by quad +// 4 float by color, 4 colors by quad + +// 6 int by quad (indices) + +// 6 int by quad (indices) + +// Indices can be initialized right now + +//-------------------------------------------------------------------------------------------- + +// Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs +//-------------------------------------------------------------------------------------------- + +// Initialize Quads VAO + +// Quads - Vertex buffers binding and attributes enable +// Vertex position buffer (shader-location = 0) + +// Vertex texcoord buffer (shader-location = 1) + +// Vertex color buffer (shader-location = 3) + +// Fill index buffer + +// Unbind the current VAO + +//-------------------------------------------------------------------------------------------- + +// Init draw calls tracking system +//-------------------------------------------------------------------------------------------- + +//batch.draws[i].vaoId = 0; +//batch.draws[i].shaderId = 0; + +//batch.draws[i].RLGL.State.projection = rlMatrixIdentity(); +//batch.draws[i].RLGL.State.modelview = rlMatrixIdentity(); + +// Record buffer count +// Reset draws counter +// Reset depth value +//-------------------------------------------------------------------------------------------- + +// Unload default internal buffers vertex data from CPU and GPU + +// Unbind everything + +// Unload all vertex buffers data + +// Unbind VAO attribs data + +// Delete VBOs from GPU (VRAM) + +// Delete VAOs from GPU (VRAM) + +// Free vertex arrays memory from CPU (RAM) + +// Unload arrays + +// Draw render batch +// NOTE: We require a pointer to reset batch and increase current buffer (multi-buffer) + +// Update batch vertex buffers +//------------------------------------------------------------------------------------------------------------ +// NOTE: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0) +// TODO: If no data changed on the CPU arrays --> No need to re-update GPU arrays (use a change detector flag?) + +// Activate elements VAO + +// Vertex positions buffer + +//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*3*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].vertices, GL_DYNAMIC_DRAW); // Update all buffer + +// Texture coordinates buffer + +//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*2*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].texcoords, GL_DYNAMIC_DRAW); // Update all buffer + +// Colors buffer + +//glBufferData(GL_ARRAY_BUFFER, sizeof(float)*4*4*batch->vertexBuffer[batch->currentBuffer].elementCount, batch->vertexBuffer[batch->currentBuffer].colors, GL_DYNAMIC_DRAW); // Update all buffer + +// NOTE: glMapBuffer() causes sync issue. +// If GPU is working with this buffer, glMapBuffer() will wait(stall) until GPU to finish its job. +// To avoid waiting (idle), you can call first glBufferData() with NULL pointer before glMapBuffer(). +// If you do that, the previous data in PBO will be discarded and glMapBuffer() returns a new +// allocated pointer immediately even if GPU is still working with the previous data. + +// Another option: map the buffer object into client's memory +// Probably this code could be moved somewhere else... +// batch->vertexBuffer[batch->currentBuffer].vertices = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); +// if (batch->vertexBuffer[batch->currentBuffer].vertices) +// { +// Update vertex data +// } +// glUnmapBuffer(GL_ARRAY_BUFFER); + +// Unbind the current VAO + +//------------------------------------------------------------------------------------------------------------ + +// Draw batch vertex buffers (considering VR stereo if required) +//------------------------------------------------------------------------------------------------------------ + +// Setup current eye viewport (half screen width) + +// Set current eye view offset to modelview matrix + +// Set current eye projection matrix + +// Draw buffers + +// Set current shader and upload current MVP matrix + +// Create modelview-projection matrix and upload to shader + +// Bind vertex attrib: position (shader-location = 0) + +// Bind vertex attrib: texcoord (shader-location = 1) + +// Bind vertex attrib: color (shader-location = 3) + +// Setup some default shader values + +// Active default sampler2D: texture0 + +// Activate additional sampler textures +// Those additional textures will be common for all draw calls of the batch + +// Activate default sampler2D texture0 (one texture is always active for default batch shader) +// NOTE: Batch system accumulates calls by texture0 changes, additional textures are enabled for all the draw calls + +// Bind current draw call texture, activated as GL_TEXTURE0 and Bound to sampler2D texture0 by default + +// We need to define the number of indices to be processed: elementCount*6 +// NOTE: The final parameter tells the GPU the offset in bytes from the +// start of the index buffer to the location of the first index to process + +// Unbind textures + +// Unbind VAO + +// Unbind shader program + +// Restore viewport to default measures + +//------------------------------------------------------------------------------------------------------------ + +// Reset batch buffers +//------------------------------------------------------------------------------------------------------------ +// Reset vertex counter for next frame + +// Reset depth for next draw + +// Restore projection/modelview matrices + +// Reset RLGL.currentBatch->draws array + +// Reset active texture units for next batch + +// Reset draws counter to one draw for the batch + +//------------------------------------------------------------------------------------------------------------ + +// Change to next buffer in the list (in case of multi-buffering) + +// Set the active render batch for rlgl + +// Update and draw internal render batch + +// NOTE: Stereo rendering is checked inside + +// Check internal buffer overflow for a given number of vertex +// and force a rlRenderBatch draw call if required + +// Store current primitive drawing mode and texture id + +// NOTE: Stereo rendering is checked inside + +// Restore state of last batch so we can continue adding vertices + +// Textures data management +//----------------------------------------------------------------------------------------- +// Convert image data to OpenGL texture (returns OpenGL valid Id) + +// Free any old binding + +// Check texture format support by OpenGL 1.1 (compressed textures not supported) + +// GRAPHICS_API_OPENGL_11 + +// Generate texture id + +// Mipmap data offset, only used for tracelog + +// NOTE: Added pointer math separately from function to avoid UBSAN complaining + +// Load the different mipmap levels + +// Increment offset position to next mipmap +// Increment data pointer to next mipmap + +// Security check for NPOT textures + +// Texture parameters configuration +// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used + +// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used + +// Set texture to repeat on x-axis +// Set texture to repeat on y-axis + +// NOTE: If using negative texture coordinates (LoadOBJ()), it does not work! +// Set texture to clamp on x-axis +// Set texture to clamp on y-axis + +// Set texture to repeat on x-axis +// Set texture to repeat on y-axis + +// Magnification and minification filters +// Alternative: GL_LINEAR +// Alternative: GL_LINEAR + +// Activate Trilinear filtering if mipmaps are available + +// At this point we have the texture loaded in GPU and texture parameters configured + +// NOTE: If mipmaps were not in data, they are not generated automatically + +// Unbind current texture + +// Load depth texture/renderbuffer (to be attached to fbo) +// WARNING: OpenGL ES 2.0 requires GL_OES_depth_texture and WebGL requires WEBGL_depth_texture extensions + +// In case depth textures not supported, we force renderbuffer usage + +// NOTE: We let the implementation to choose the best bit-depth +// Possible formats: GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32 and GL_DEPTH_COMPONENT32F + +// WARNING: WebGL platform requires unsized internal format definition (GL_DEPTH_COMPONENT) +// while other platforms using OpenGL ES 2.0 require/support sized internal formats depending on the GPU capabilities + +// Create the renderbuffer that will serve as the depth attachment for the framebuffer +// NOTE: A renderbuffer is simpler than a texture and could offer better performance on embedded devices + +// Load texture cubemap +// NOTE: Cubemap data is expected to be 6 images in a single data array (one after the other), +// expected the following convention: +X, -X, +Y, -Y, +Z, -Z + +// Load cubemap faces + +// Set cubemap texture sampling parameters + +// Flag not supported on OpenGL ES 2.0 + +// Update already loaded texture in GPU with new data +// NOTE: We don't know safely if internal texture format is the expected one... + +// Get OpenGL internal formats and data type from raylib PixelFormat + +// NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA + +// NOTE: Requires extension OES_texture_float +// NOTE: Requires extension OES_texture_float +// NOTE: Requires extension OES_texture_float + +// defined(GRAPHICS_API_OPENGL_ES2) +// NOTE: Requires extension OES_texture_half_float +// NOTE: Requires extension OES_texture_half_float +// NOTE: Requires extension OES_texture_half_float + +// NOTE: Requires OpenGL ES 2.0 or OpenGL 4.3 +// NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 +// NOTE: Requires OpenGL ES 3.0 or OpenGL 4.3 +// NOTE: Requires PowerVR GPU +// NOTE: Requires PowerVR GPU +// NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 +// NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3 + +// Unload texture from GPU memory + +// Generate mipmap data for selected texture +// NOTE: Only supports GPU mipmap generation + +// Check if texture is power-of-two (POT) + +//glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorithm: GL_FASTEST, GL_NICEST, GL_DONT_CARE +// Generate mipmaps automatically + +// Read texture pixel data + +// NOTE: Using texture id, we can retrieve some texture info (but not on OpenGL ES 2.0) +// Possible texture info: GL_TEXTURE_RED_SIZE, GL_TEXTURE_GREEN_SIZE, GL_TEXTURE_BLUE_SIZE, GL_TEXTURE_ALPHA_SIZE +//int width, height, format; +//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); +//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); +//glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); + +// NOTE: Each row written to or read from by OpenGL pixel operations like glGetTexImage are aligned to a 4 byte boundary by default, which may add some padding. +// Use glPixelStorei to modify padding with the GL_[UN]PACK_ALIGNMENT setting. +// GL_PACK_ALIGNMENT affects operations that read from OpenGL memory (glReadPixels, glGetTexImage, etc.) +// GL_UNPACK_ALIGNMENT affects operations that write to OpenGL memory (glTexImage, etc.) + +// glGetTexImage() is not available on OpenGL ES 2.0 +// Texture width and height are required on OpenGL ES 2.0. There is no way to get it from texture id. +// Two possible Options: +// 1 - Bind texture to color fbo attachment and glReadPixels() +// 2 - Create an fbo, activate it, render quad with texture, glReadPixels() +// We are using Option 1, just need to care for texture format on retrieval +// NOTE: This behaviour could be conditioned by graphic driver... + +// Attach our texture to FBO + +// We read data as RGBA because FBO texture is configured as RGBA, despite binding another texture format + +// Clean up temporal fbo + +// Read screen pixel data (color buffer) + +// NOTE 1: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer +// NOTE 2: We are getting alpha channel! Be careful, it can be transparent if not cleared properly! + +// Flip image vertically! + +// Flip line + +// Set alpha component value to 255 (no trasparent image retrieval) +// NOTE: Alpha value has already been applied to RGB in framebuffer, we don't need it! + +// NOTE: image data should be freed + +// Framebuffer management (fbo) +//----------------------------------------------------------------------------------------- +// Load a framebuffer to be used for rendering +// NOTE: No textures attached + +// Create the framebuffer object +// Unbind any framebuffer + +// Attach color buffer texture to an fbo (unloads previous attachment) +// NOTE: Attach type: 0-Color, 1-Depth renderbuffer, 2-Depth texture + +// Verify render texture is complete + +// Unload framebuffer from GPU memory +// NOTE: All attached textures/cubemaps/renderbuffers are also deleted + +// Query depth attachment to automatically delete texture/renderbuffer + +// Bind framebuffer to query depth texture type + +// TODO: Review warning retrieving object name in WebGL +// WARNING: WebGL: INVALID_ENUM: getFramebufferAttachmentParameter: invalid parameter name +// https://registry.khronos.org/webgl/specs/latest/1.0/ + +// NOTE: If a texture object is deleted while its image is attached to the *currently bound* framebuffer, +// the texture image is automatically detached from the currently bound framebuffer. + +// Vertex data management +//----------------------------------------------------------------------------------------- +// Load a new attributes buffer + +// Load a new attributes element buffer + +// Enable vertex buffer (VBO) + +// Disable vertex buffer (VBO) + +// Enable vertex buffer element (VBO element) + +// Disable vertex buffer element (VBO element) + +// Update vertex buffer with new data +// NOTE: dataSize and offset must be provided in bytes + +// Update vertex buffer elements with new data +// NOTE: dataSize and offset must be provided in bytes + +// Enable vertex array object (VAO) + +// Disable vertex array object (VAO) + +// Enable vertex attribute index + +// Disable vertex attribute index + +// Draw vertex array + +// Draw vertex array elements + +// NOTE: Added pointer math separately from function to avoid UBSAN complaining + +// Draw vertex array instanced + +// Draw vertex array elements instanced + +// NOTE: Added pointer math separately from function to avoid UBSAN complaining + +// Enable vertex state pointer + +//case GL_INDEX_ARRAY: if (buffer != NULL) glIndexPointer(GL_SHORT, 0, buffer); break; // Indexed colors + +// Disable vertex state pointer + +// Load vertex array object (VAO) + +// Set vertex attribute + +// Set vertex attribute divisor + +// Unload vertex array object (VAO) + +// Unload vertex buffer (VBO) + +//TRACELOG(RL_LOG_INFO, "VBO: Unloaded vertex data from VRAM (GPU)"); + +// Shaders management +//----------------------------------------------------------------------------------------------- +// Load shader from code strings +// NOTE: If shader string is NULL, using default vertex/fragment shaders + +// Compile vertex shader (if provided) + +// In case no vertex shader was provided or compilation failed, we use default vertex shader + +// Compile fragment shader (if provided) + +// In case no fragment shader was provided or compilation failed, we use default fragment shader + +// In case vertex and fragment shader are the default ones, no need to recompile, we can just assign the default shader program id + +// One of or both shader are new, we need to compile a new shader program + +// We can detach and delete vertex/fragment shaders (if not default ones) +// NOTE: We detach shader before deletion to make sure memory is freed + +// WARNING: Shader program linkage could fail and returned id is 0 + +// WARNING: Shader program linkage could fail and returned id is 0 + +// In case shader program loading failed, we assign default shader + +// In case shader loading fails, we return the default shader + +/* +else +{ + // Get available shader uniforms + // NOTE: This information is useful for debug... + int uniformCount = -1; + glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &uniformCount); + + for (int i = 0; i < uniformCount; i++) + { + int namelen = -1; + int num = -1; + char name[256] = { 0 }; // Assume no variable names longer than 256 + GLenum type = GL_ZERO; + + // Get the name of the uniforms + glGetActiveUniform(id, i, sizeof(name) - 1, &namelen, &num, &type, name); + + name[namelen] = 0; + TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", id, name, glGetUniformLocation(id, name)); + } +} +*/ + +// Compile custom shader and return shader id + +//case GL_GEOMETRY_SHADER: + +//case GL_GEOMETRY_SHADER: + +// Load custom shader strings and return program id + +// NOTE: Default attribute shader locations must be Bound before linking + +// NOTE: If some attrib name is no found on the shader, it locations becomes -1 + +// NOTE: All uniform variables are intitialised to 0 when a program links + +// Get the size of compiled shader program (not available on OpenGL ES 2.0) +// NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. +//GLint binarySize = 0; +//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + +// Unload shader program + +// Get shader location uniform + +//if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shaderId, uniformName); +//else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shaderId, uniformName, location); + +// Get shader location attribute + +//if (location == -1) TRACELOG(RL_LOG_WARNING, "SHADER: [ID %i] Failed to find shader attribute: %s", shaderId, attribName); +//else TRACELOG(RL_LOG_INFO, "SHADER: [ID %i] Shader attribute (%s) set at location: %i", shaderId, attribName, location); + +// Set shader value uniform + +// Set shader value attribute + +// Set shader value uniform matrix + +// Set shader value uniform sampler + +// Check if texture is already active + +// Register a new active texture for the internal batch system +// NOTE: Default texture is always activated as GL_TEXTURE0 + +// Activate new texture unit +// Save texture id for binding on drawing + +// Set shader currently active (id and locations) + +// Load compute shader program + +// NOTE: All uniform variables are intitialised to 0 when a program links + +// Get the size of compiled shader program (not available on OpenGL ES 2.0) +// NOTE: If GL_LINK_STATUS is GL_FALSE, program binary length is zero. +//GLint binarySize = 0; +//glGetProgramiv(id, GL_PROGRAM_BINARY_LENGTH, &binarySize); + +// Dispatch compute shader (equivalent to *draw* for graphics pilepine) + +// Load shader storage buffer object (SSBO) + +// Clear buffer data to 0 + +// Unload shader storage buffer object (SSBO) + +// Update SSBO buffer data + +// Get SSBO buffer size + +// Read SSBO buffer data (GPU->CPU) + +// Bind SSBO buffer + +// Copy SSBO buffer data + +// Bind image texture + +// Matrix state management +//----------------------------------------------------------------------------------------- +// Get internal modelview matrix + +// Get internal projection matrix + +// Get internal accumulated transform matrix + +// TODO: Consider possible transform matrices in the RLGL.State.stack +// Is this the right order? or should we start with the first stored matrix instead of the last one? +//Matrix matStackTransform = rlMatrixIdentity(); +//for (int i = RLGL.State.stackCounter; i > 0; i--) matStackTransform = rlMatrixMultiply(RLGL.State.stack[i], matStackTransform); + +// Get internal projection matrix for stereo render (selected eye) + +// Get internal view offset matrix for stereo render (selected eye) + +// Set a custom modelview matrix (replaces internal modelview matrix) + +// Set a custom projection matrix (replaces internal projection matrix) + +// Set eyes projection matrices for stereo rendering + +// Set eyes view offsets matrices for stereo rendering + +// Load and draw a quad in NDC + +// Positions Texcoords + +// Gen VAO to contain VBO + +// Gen and fill vertex buffer (VBO) + +// Bind vertex attributes (position, texcoords) + +// Positions + +// Texcoords + +// Draw quad + +// Delete buffers (VBO and VAO) + +// Load and draw a cube in NDC + +// Positions Normals Texcoords + +// Gen VAO to contain VBO + +// Gen and fill vertex buffer (VBO) + +// Bind vertex attributes (position, normals, texcoords) + +// Positions + +// Normals + +// Texcoords + +// Draw cube + +// Delete VBO and VAO + +// Get name string for pixel format + +// 8 bit per pixel (no alpha) +// 8*2 bpp (2 channels) +// 16 bpp +// 24 bpp +// 16 bpp (1 bit alpha) +// 16 bpp (4 bit alpha) +// 32 bpp +// 32 bpp (1 channel - float) +// 32*3 bpp (3 channels - float) +// 32*4 bpp (4 channels - float) +// 16 bpp (1 channel - half float) +// 16*3 bpp (3 channels - half float) +// 16*4 bpp (4 channels - half float) +// 4 bpp (no alpha) +// 4 bpp (1 bit alpha) +// 8 bpp +// 8 bpp +// 4 bpp +// 4 bpp +// 8 bpp +// 4 bpp +// 4 bpp +// 8 bpp +// 2 bpp + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Load default shader (just vertex positioning and texture coloring) +// NOTE: This shader program is used for internal buffers +// NOTE: Loaded: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs + +// NOTE: All locations must be reseted to -1 (no location) + +// Vertex shader directly defined, no external file required + +// Precision required for OpenGL ES2 (WebGL) (on some browsers) + +// Fragment shader directly defined, no external file required + +// Precision required for OpenGL ES2 (WebGL) + +// NOTE: Compiled vertex/fragment shaders are not deleted, +// they are kept for re-use as default shaders in case some shader loading fails +// Compile default vertex shader +// Compile default fragment shader + +// Set default shader locations: attributes locations + +// Set default shader locations: uniform locations + +// Unload default shader +// NOTE: Unloads: RLGL.State.defaultShaderId, RLGL.State.defaultShaderLocs + +// Get compressed format official GL identifier name + +// GL_EXT_texture_compression_s3tc + +// GL_3DFX_texture_compression_FXT1 + +// GL_IMG_texture_compression_pvrtc + +// GL_OES_compressed_ETC1_RGB8_texture + +// GL_ARB_texture_compression_rgtc + +// GL_ARB_texture_compression_bptc + +// GL_ARB_ES3_compatibility + +// GL_KHR_texture_compression_astc_hdr + +// RLGL_SHOW_GL_DETAILS_INFO + +// GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2 + +// Get pixel data size in bytes (image or texture) +// NOTE: Size depends on pixel format + +// Size in bytes +// Bits per pixel + +// Total data size in bytes + +// Most compressed formats works on 4x4 blocks, +// if texture is smaller, minimum dataSize is 8 or 16 + +// Auxiliar math functions + +// Get identity matrix + +// Get two matrix multiplication +// NOTE: When multiplying matrices... the order matters! + +// RLGL_IMPLEMENTATION