diff --git a/assets/blender/test_level_blend/NurbsPath.glb b/assets/blender/test_level_blend/NurbsPath.glb index abf8869..88db946 100644 --- a/assets/blender/test_level_blend/NurbsPath.glb +++ b/assets/blender/test_level_blend/NurbsPath.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:32d2ebbdb78fe6f6121051c11926a24aba3bbfc672eb7878c4f60745a1c7719d -size 19628 +oid sha256:7c6373e6eb37e5b74839e2ad86e90ed3eadfe5685d72ce6567c1d25bc74cc01d +size 20924 diff --git a/assets/blender/test_level_blend/Plane.glb b/assets/blender/test_level_blend/Plane.glb index b8903ae..3d25d0f 100644 --- a/assets/blender/test_level_blend/Plane.glb +++ b/assets/blender/test_level_blend/Plane.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c8c21befe6000244cb579414a283dd1985ede41529de5136810bcb971ed484bb -size 1112 +oid sha256:17adf2dea120b849a441540e9c93c4dc5ecfba6b802f730e89d8bc26c1e59c1a +size 2404 diff --git a/assets/blender/test_level_blend/Scene.scn b/assets/blender/test_level_blend/Scene.scn index 70ace8d..779e3e6 100644 --- a/assets/blender/test_level_blend/Scene.scn +++ b/assets/blender/test_level_blend/Scene.scn @@ -1,45 +1,45 @@ (inst :model "assets/blender/testblend_blend/Bakery.glb" - :pos (0.000000 0.000000 12.000000) + :pos (1.000000 0.000000 -13.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/test_level_blend/Plane.glb" - :pos (0.000000 -1.000000 0.000000) + :pos (0.000000 -1.000000 -0.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (22.469545 22.469545 22.469545)) (inst :model "assets/blender/testblend_blend/Fire_Station.glb" - :pos (9.000000 0.000000 13.000000) + :pos (10.500000 0.000000 -22.500000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/testblend_blend/Gas_Station_Shop.glb" - :pos (-8.000000 0.000000 11.000000) + :pos (-7.000000 0.000000 -12.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/testblend_blend/Gas_Station_Shop.glb" - :pos (-16.000000 0.000000 11.000000) + :pos (-16.000000 0.000000 -11.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/testblend_blend/Gas_Station_Shop.glb" - :pos (-15.559284 1.609015 0.259853) + :pos (-20.000000 -1.000000 -1.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/testblend_blend/Green_House.glb" - :pos (14.000000 0.000000 -7.000000) + :pos (14.000000 0.000000 7.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/testblend_blend/Hotel.glb" - :pos (8.000000 0.000000 -18.000000) + :pos (8.000000 0.000000 18.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) (inst :model "assets/blender/test_level_blend/NurbsPath.glb" - :pos (0.000000 1.000000 0.000000) + :pos (-4.000000 0.000000 12.000000) :rot (0.000000 0.000000 0.000000 1.000000) :scale (1.000000 1.000000 1.000000)) diff --git a/assets/blender/testblend_blend/Bakery.glb b/assets/blender/testblend_blend/Bakery.glb index 0b12e88..ab312ea 100644 --- a/assets/blender/testblend_blend/Bakery.glb +++ b/assets/blender/testblend_blend/Bakery.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f96d7e9484368541f5d0f5eb66444273f314e9ea57e9544999ce7a2d3cb90c1b -size 188908 +oid sha256:27e1735981cf49e5ec7d37feffeefdf4f4e8dc6ba8c31833d41d36414f0706f1 +size 188860 diff --git a/assets/blender/testblend_blend/Fire_Station.glb b/assets/blender/testblend_blend/Fire_Station.glb index d24ff01..11122d0 100644 --- a/assets/blender/testblend_blend/Fire_Station.glb +++ b/assets/blender/testblend_blend/Fire_Station.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a506c5b05f6be06f6a4cb3092b65623ac805b9fc6c13d2295605b0730edc6034 -size 381548 +oid sha256:0bad5966c7ddfa70289b8a7dc93be051d1e1727edb671ed4821845b44649dd51 +size 381492 diff --git a/assets/blender/testblend_blend/Gas_Station_Shop.glb b/assets/blender/testblend_blend/Gas_Station_Shop.glb index be4c8a2..dd0d3df 100644 --- a/assets/blender/testblend_blend/Gas_Station_Shop.glb +++ b/assets/blender/testblend_blend/Gas_Station_Shop.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9e893c43927628cb56fc5d9d6d344a062d46eba8d8c9ef716e0acf99a09c36e4 -size 157404 +oid sha256:2768550bc301c0136e254e836e5857eb54c7af15e96a3ce66773f8985af528aa +size 157344 diff --git a/assets/blender/testblend_blend/Green_House.glb b/assets/blender/testblend_blend/Green_House.glb index c5e8c04..3a12ecc 100644 --- a/assets/blender/testblend_blend/Green_House.glb +++ b/assets/blender/testblend_blend/Green_House.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:97ff0340948c89b346826f2571c3206335a895eb2a222eb94ccdc929fdcda5bf -size 83088 +oid sha256:6679212fa665106031e48610449c99c25ed1dce65e5b02a01baf3913813b39a7 +size 82976 diff --git a/assets/blender/testblend_blend/Hotel.glb b/assets/blender/testblend_blend/Hotel.glb index c73baa5..d18773e 100644 --- a/assets/blender/testblend_blend/Hotel.glb +++ b/assets/blender/testblend_blend/Hotel.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea2eda2ea37765ff154e9ee33f9bde7afe4e671bb7a74088f1087122e24db897 -size 4459408 +oid sha256:660dc54468100dc133be98fdf1ebf216e1cb4329223e34c5e5f250ad7c8cbd4e +size 4459304 diff --git a/blender/batch_export.py b/blender/batch_export.py index bd47d3d..cef8895 100644 --- a/blender/batch_export.py +++ b/blender/batch_export.py @@ -1,6 +1,7 @@ import bpy import os import pathlib +import contextlib # Ensure blend file is saved blend_filepath = bpy.data.filepath @@ -9,6 +10,26 @@ if not blend_filepath: assert bpy.context.scene is not None +@contextlib.contextmanager +def temp_scene(name: str): + original_scene = bpy.context.scene + assert original_scene is not None + temp_scene = bpy.data.scenes.new(name) + assert bpy.context.window is not None + + try: + bpy.context.window.scene = temp_scene + yield temp_scene + finally: + assert bpy.context.window is not None + bpy.context.window.scene = original_scene + print(f'removing scene {temp_scene}') + bpy.data.scenes.remove(temp_scene) + +scene = bpy.context.scene + +export_scene = bpy.data.scenes.new('__export') + def clean_blend_path(blend_path: str) -> str: return os.path.join(os.path.dirname(blend_path), bpy.path.clean_name(os.path.basename(blend_path))) @@ -39,13 +60,18 @@ def export_object_as_glb(obj: bpy.types.Object, export_path: str): full_export_path = os.path.join(assets_path, export_path) pathlib.Path(os.path.dirname(full_export_path)).mkdir(parents=True, exist_ok=True) - bpy.ops.object.select_all(action='DESELECT') - obj.select_set(True) + if obj.instance_type == 'COLLECTION' and obj.instance_collection: + with temp_scene('__export') as scn: + scn.collection.children.link(obj.instance_collection) + bpy.ops.export_scene.gltf(filepath=full_export_path, use_active_scene=True, export_apply=True) + else: + bpy.ops.object.select_all(action='DESELECT') + obj.select_set(True) + assert bpy.context.view_layer is not None + bpy.context.view_layer.objects.active = obj - assert bpy.context.view_layer is not None - bpy.context.view_layer.objects.active = obj + bpy.ops.export_scene.gltf(filepath=full_export_path, use_selection=True, export_apply=True) - bpy.ops.export_scene.gltf(filepath=full_export_path, use_selection=True, export_apply=True) print(f"Exported {obj.name} -> {export_path}") # Collect all visible, non-hidden objects in the scene @@ -70,7 +96,7 @@ for obj in visible_objects: instance_sexpr = ( '(inst' f'\n\t:model "assets/{model_path}"' - f'\n\t:pos ({loc.x:.6f} {loc.z:.6f} {loc.y:.6f})' + f'\n\t:pos ({loc.x:.6f} {loc.z:.6f} {-loc.y:.6f})' f'\n\t:rot ({rot.x:.6f} {rot.y:.6f} {rot.z:.6f} {rot.w:.6f})' f'\n\t:scale ({scale.x:.6f} {scale.y:.6f} {scale.z:.6f}))' ) diff --git a/common/name/name.odin b/common/name/name.odin index cc60140..d200979 100644 --- a/common/name/name.odin +++ b/common/name/name.odin @@ -5,6 +5,7 @@ package name import "core:mem" import "core:strings" import "core:sync" +import "libs:tracy" // When enabled name globals will be initialized automatically NAME_STATIC_INIT :: #config(NAME_STATIC_INIT, true) @@ -61,23 +62,36 @@ when NAME_STATIC_INIT { } from_string :: proc(str: string) -> Name { - sync.atomic_rw_mutex_guard(&global_container.lock) - existing, ok := global_container.names_lookup[str] + tracy.Zone() + + existing: Name + ok: bool + { + sync.atomic_rw_mutex_shared_guard(&global_container.lock) + existing, ok = global_container.names_lookup[str] + } if ok { return existing } else { - new_str := strings.clone( + sync.atomic_rw_mutex_guard(&global_container.lock) + + new_str := strings.clone_to_cstring( str, mem.dynamic_arena_allocator(&global_container.names_allocator), ) idx := u32(len(global_container.names_array)) - append(&global_container.names_array, new_str) + append(&global_container.names_array, string(new_str)) global_container.names_lookup[str] = Name(idx) return Name(idx) } } +from_cstring :: proc(str: cstring) -> Name { + return from_string(string(str)) +} + to_string :: proc(name: Name) -> string { + tracy.Zone() sync.atomic_rw_mutex_shared_guard(&global_container.lock) return global_container.names_array[name] } diff --git a/game/assets/assets.odin b/game/assets/assets.odin index 08daa71..96277e3 100644 --- a/game/assets/assets.odin +++ b/game/assets/assets.odin @@ -5,28 +5,17 @@ import "common:name" import "core:log" import "core:math" import lg "core:math/linalg" -import "core:strconv" -import "game:debug" -import "game:halfedge" +import "core:sync/chan" import "game:physics/bvh" import "game:physics/collision" import "libs:physfs" import rl "libs:raylib" -import "libs:raylib/rlgl" import "libs:tracy" + _ :: math -@(private = "file") -g_assetman_instance: ^Asset_Manager - -init :: proc(assetman: ^Asset_Manager) { - g_assetman_instance = assetman -} - -manager :: #force_inline proc() -> ^Asset_Manager { - return g_assetman_instance -} +DEV_BUILD :: #config(DEV, false) Loaded_BVH :: struct { // AABB of all bvhs @@ -35,7 +24,6 @@ Loaded_BVH :: struct { bvh: bvh.BVH, vertices: []rl.Vector3, indices: []u16, - modtime: physfs.sint64, } Loaded_Convex :: struct { @@ -45,10 +33,6 @@ Loaded_Convex :: struct { total_volume: f32, } -Loaded_Curve_2D :: struct { - points: [][2]f32, -} - destroy_loaded_bvh :: proc(loaded_bvh: ^Loaded_BVH) { tracy.Zone() @@ -71,31 +55,73 @@ Scene_Desc :: struct { instances: []Scene_Instance, } +Asset_Type :: enum { + Texture, + Model, + Shader, + Sound, + Music, + Curve_1D, + Curve_2D, + Scene, + BVH, + Convex, +} + +Curve_1D :: []f32 + +Asset :: union { + rl.Texture2D, + rl.Model, + Loaded_Shader, + rl.Sound, + rl.Music, + Curve_1D, + Curve_2D, + Scene_Desc, + Loaded_BVH, + Loaded_Convex, +} + +Asset_Key :: struct { + path: name.Name, + type: Asset_Type, +} + +Asset_Entry :: struct { + asset: Asset, + modtime: physfs.sint64, + + // Current modtime on file system, used to detect when asset changes + fs_modtime: physfs.sint64, +} + Asset_Manager :: struct { - textures: Asset_Cache(rl.Texture2D), - models: Asset_Cache(rl.Model), - shaders: Asset_Cache(Loaded_Shader), - sounds: Asset_Cache(rl.Sound), - music: Asset_Cache(rl.Music), - curves_1d: Asset_Cache([]f32), - curves_2d: Asset_Cache(Curve_2D), - scenes: Asset_Cache(Scene_Desc), - bvhs: map[cstring]Loaded_BVH, - curves: map[cstring]Loaded_Curve_2D, + assets: map[Asset_Key]Asset_Entry, + watcher: Asset_Modtime_Watcher, } Asset_Cache_Entry :: struct($E: typeid) { - value: E, - modtime: i64, + value: E, + modtime: i64, + fs_modtime: i64, } Asset_Cache_Loader_Payload :: union { cstring, } -Asset_Cache_Loader :: struct($E: typeid) { - load: proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (E, bool), - unload: proc(value: E), +Asset_Cache_Loader :: struct { + load: proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ), + unload: proc(value: Asset), + should_reload: proc(assetman: ^Asset_Manager, key: Asset_Key, entry: Asset_Entry) -> bool, } Asset_Cache :: struct($E: typeid) { @@ -103,7 +129,6 @@ Asset_Cache :: struct($E: typeid) { loader: Asset_Cache_Loader(E), } - Shader_Location :: enum { Ambient, LightDir, @@ -126,58 +151,100 @@ Loaded_Shader :: struct { locations: Shader_Location_Array, } -SHADER_LOADER :: Asset_Cache_Loader(Loaded_Shader) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Loaded_Shader, bool) { +SHADER_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { shader := rl.LoadShader(path, payload.(cstring)) return Loaded_Shader{shader = shader}, rl.IsShaderValid(shader) }, - unload = proc(shader: Loaded_Shader) { - rl.UnloadShader(shader.shader) + unload = proc(asset: Asset) { + rl.UnloadShader(asset.(Loaded_Shader).shader) }, } -SOUND_LOADER :: Asset_Cache_Loader(rl.Sound) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Sound, bool) { +SOUND_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { sound := rl.LoadSound(path) return sound, rl.IsSoundValid(sound) }, - unload = proc(sound: rl.Sound) { - rl.UnloadSound(sound) + unload = proc(asset: Asset) { + rl.UnloadSound(asset.(rl.Sound)) }, } -MUSIC_LOADER :: Asset_Cache_Loader(rl.Music) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Music, bool) { +MUSIC_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { music := rl.LoadMusicStream(path) return music, rl.IsMusicValid(music) }, - unload = proc(music: rl.Music) { - rl.UnloadMusicStream(music) + unload = proc(asset: Asset) { + rl.UnloadMusicStream(asset.(rl.Music)) }, } -MODEL_LOADER :: Asset_Cache_Loader(rl.Model) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Model, bool) { +MODEL_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { model := rl.LoadModel(path) return model, rl.IsModelValid(model) }, - unload = proc(model: rl.Model) { - rl.UnloadModel(model) + unload = proc(asset: Asset) { + rl.UnloadModel(asset.(rl.Model)) }, } -TEXTURE_LOADER :: Asset_Cache_Loader(rl.Texture2D) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (rl.Texture2D, bool) { +TEXTURE_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { texture := rl.LoadTexture(path) return texture, rl.IsTextureValid(texture) }, - unload = proc(texture: rl.Texture2D) { - rl.UnloadTexture(texture) + unload = proc(asset: Asset) { + rl.UnloadTexture(asset.(rl.Texture2D)) }, } -CURVE_1D_CSV_LOADER :: Asset_Cache_Loader([]f32) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> ([]f32, bool) { +CURVE_1D_CSV_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { data, err := physfs.read_entire_file(string(path), context.temp_allocator) if err != nil { log.errorf("Failed to read curve: %s, %v", path, err) @@ -192,13 +259,20 @@ CURVE_1D_CSV_LOADER :: Asset_Cache_Loader([]f32) { return values, true }, - unload = proc(values: []f32) { - delete(values) + unload = proc(asset: Asset) { + delete(asset.(Curve_1D)) }, } -CURVE_2D_CSV_LOADER :: Asset_Cache_Loader(Curve_2D) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Curve_2D, bool) { +CURVE_2D_CSV_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { data, err := physfs.read_entire_file(string(path), context.temp_allocator) if err != nil { log.errorf("Failed to read curve: %s, %v", path, err) @@ -211,15 +285,22 @@ CURVE_2D_CSV_LOADER :: Asset_Cache_Loader(Curve_2D) { log.errorf("Failed to parse curve: %s, %v", path, err2) } - return curve.points, true + return curve, true }, - unload = proc(curve: Curve_2D) { - delete(curve) + unload = proc(asset: Asset) { + delete(asset.(Curve_2D)) }, } -SCENE_DESC_LOADER :: Asset_Cache_Loader(Scene_Desc) { - load = proc(path: cstring, payload: Asset_Cache_Loader_Payload) -> (Scene_Desc, bool) { +SCENE_DESC_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { data, err := physfs.read_entire_file(string(path), context.temp_allocator) if err != nil { log.errorf("Failed to read curve: %s, %v", path, err) @@ -311,199 +392,31 @@ SCENE_DESC_LOADER :: Asset_Cache_Loader(Scene_Desc) { return Scene_Desc{instances = instances[:num_instances]}, true }, - unload = proc(scene_desc: Scene_Desc) { - delete(scene_desc.instances) + unload = proc(asset: Asset) { + delete(asset.(Scene_Desc).instances) }, } -assetman_init :: proc(assetman: ^Asset_Manager) { - assetman.models = { - loader = MODEL_LOADER, - } - assetman.shaders = { - loader = SHADER_LOADER, - } - assetman.sounds = { - loader = SOUND_LOADER, - } - assetman.music = { - loader = MUSIC_LOADER, - } - assetman.textures = { - loader = TEXTURE_LOADER, - } - assetman.curves_1d = { - loader = CURVE_1D_CSV_LOADER, - } - assetman.curves_2d = { - loader = CURVE_2D_CSV_LOADER, - } - assetman.scenes = { - loader = SCENE_DESC_LOADER, - } -} +BVH_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { + model_asset, _, model_res := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Model}, + ) -Asset_Cache_Result :: enum { - Cached, - Loaded, - Reloaded, - Error, -} - -assetcache_fetch_or_load :: proc( - ac: ^$T/Asset_Cache($E), - path: cstring, - payload: Asset_Cache_Loader_Payload = nil, - force_no_reload := false, -) -> ( - value: E, - modtime: physfs.sint64, - result: Asset_Cache_Result, -) { - tracy.Zone() - - existing, has_existing := ac.cache[path] - - if has_existing { - new_modtime := physfs.getLastModTime(path) - - if force_no_reload || existing.modtime == new_modtime { - result = .Cached - return existing.value, new_modtime, result - } else { - // Try to load the new version - - new_value, ok := ac.loader.load(path, payload) - - if ok { - result = .Reloaded - ac.loader.unload(existing.value) - ac.cache[path] = { - value = new_value, - modtime = new_modtime, - } - - log.debugf("reloaded asset: %s", path) - - return new_value, new_modtime, result - } else { - log.warnf("failed to reload asset after modification %s", path) - result = .Cached - - return existing.value, existing.modtime, result - } + if model_res == .Error { + return nil, false } - } else { - modtime = physfs.getLastModTime(path) - ok: bool - value, ok = ac.loader.load(path, payload) - if ok { - ac.cache[path] = { - value = value, - modtime = modtime, - } - result = .Loaded + model := model_asset.(rl.Model) - log.debugf("loaded asset: %s", path) - - return value, modtime, result - } else { - log.errorf("failed to load asset %s", path) - result = .Error - return {}, 0, .Error - } - } -} - -assetcache_destroy :: proc(ac: ^$T/Asset_Cache($E)) { - for _, v in ac.cache { - ac.loader.unload(v.value) - } - delete(ac.cache) -} - -get_texture :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Texture2D { - tracy.Zone() - - texture, _, _ := assetcache_fetch_or_load(&assetman.textures, path) - - return texture -} - -get_model_ex :: proc( - assetman: ^Asset_Manager, - path: cstring, - ref_modtime: physfs.sint64 = 0, // will check reload status using reference load time. When 0 reloaded will be true only if this call triggered reload -) -> ( - model: rl.Model, - modtime: physfs.sint64, - reloaded: bool, -) { - tracy.Zone() - - result: Asset_Cache_Result - model, modtime, result = assetcache_fetch_or_load(&assetman.models, path) - reloaded = result == .Reloaded || ref_modtime != modtime - - return -} - -get_model :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Model { - model, _, _ := get_model_ex(assetman, path) - - return model -} - -get_shader :: proc( - assetman: ^Asset_Manager, - vs_path: cstring, - ps_path: cstring, - location_set: Shader_Location_Set, -) -> Loaded_Shader { - loaded_shader, _, result := assetcache_fetch_or_load(&assetman.shaders, vs_path, ps_path) - - if location_set > loaded_shader.location_set || result == .Loaded || result == .Reloaded { - loaded_shader.location_set = location_set - loaded_shader.locations = {} - - for location in location_set { - loaded_shader.locations[location] = rl.GetShaderLocation( - loaded_shader.shader, - SHADER_LOCATION_NAMES[location], - ) - } - } - - return loaded_shader -} - -get_sound :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Sound { - sound, _, _ := assetcache_fetch_or_load(&assetman.sounds, path) - return sound -} - -get_music :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Music { - sound, _, _ := assetcache_fetch_or_load(&assetman.music, path) - return sound -} - -null_bvhs: []bvh.BVH - -get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> (Loaded_BVH, bool) { - tracy.Zone() - - loaded_bvh, ok := assetman.bvhs[path] - model, modtime, reloaded := get_model_ex(assetman, path, loaded_bvh.modtime) - - should_recreate := reloaded || !ok - - if ok && should_recreate { - destroy_loaded_bvh(&loaded_bvh) - delete_key(&assetman.bvhs, path) - } - - if should_recreate { vert_count := 0 indices_count := 0 @@ -543,27 +456,319 @@ get_bvh :: proc(assetman: ^Asset_Manager, path: cstring) -> (Loaded_BVH, bool) { root_aabb := mesh_bvh.bvh.nodes[0].aabb - assetman.bvhs[path] = Loaded_BVH { - aabb = root_aabb, - bvh = mesh_bvh.bvh, - vertices = vertices, - indices = indices, - modtime = modtime, + return Loaded_BVH { + aabb = root_aabb, + bvh = mesh_bvh.bvh, + vertices = vertices, + indices = indices, + }, + true + }, + unload = proc(asset: Asset) { + loaded_bvh := asset.(Loaded_BVH) + + bvh.destroy_bvh(&loaded_bvh.bvh) + delete(loaded_bvh.vertices) + delete(loaded_bvh.indices) + }, + should_reload = proc(assetman: ^Asset_Manager, key: Asset_Key, entry: Asset_Entry) -> bool { + _, modtime, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = key.path, type = .Model}, + ) + return entry.modtime != modtime + }, +} + +CONVEX_LOADER :: Asset_Cache_Loader { + load = proc( + assetman: ^Asset_Manager, + path: cstring, + payload: Asset_Cache_Loader_Payload, + ) -> ( + Asset, + bool, + ) { + tracy.Zone() + bytes, err := physfs.read_entire_file(string(path), context.temp_allocator) + + if err != nil { + log.errorf("error reading file %v %s", err) + return {}, false + } + + return parse_convex(bytes) + }, + unload = proc(asset: Asset) { + convex := asset.(Loaded_Convex) + + delete(convex.mesh.vertices) + delete(convex.mesh.edges) + delete(convex.mesh.faces) + }, +} + +ASSET_LOADERS := [Asset_Type]Asset_Cache_Loader { + .Texture = TEXTURE_LOADER, + .Model = MODEL_LOADER, + .Shader = SHADER_LOADER, + .Sound = SOUND_LOADER, + .Music = MUSIC_LOADER, + .Curve_1D = CURVE_1D_CSV_LOADER, + .Curve_2D = CURVE_2D_CSV_LOADER, + .Scene = SCENE_DESC_LOADER, + .BVH = BVH_LOADER, + .Convex = CONVEX_LOADER, +} + +assetman_init :: proc(assetman: ^Asset_Manager) { + modtime_watcher_init(&assetman.watcher) +} + +assetman_tick :: proc(assetman: ^Asset_Manager) { + tracy.Zone() + + for asset in chan.try_recv(assetman.watcher.modified_assets) { + key := Asset_Key { + path = asset.path, + type = asset.type, + } + + entry, ok := &assetman.assets[key] + + if ok { + log.debugf( + "asset changed {} {} {} {}", + name.to_string(asset.path), + asset, + entry.modtime, + asset.modtime, + ) + entry.fs_modtime = asset.modtime + } + } +} + +Asset_Cache_Result :: enum { + Cached, + Loaded, + Reloaded, + Error, +} + +assetman_fetch_or_load_internal :: proc( + assetman: ^Asset_Manager, + key: Asset_Key, + payload: Asset_Cache_Loader_Payload = nil, + force_no_reload := false, +) -> ( + value: Asset, + modtime: physfs.sint64, + result: Asset_Cache_Result, +) { + tracy.Zone() + + existing, has_existing := assetman.assets[key] + + if has_existing { + wants_reload := + ASSET_LOADERS[key.type].should_reload(assetman, key, existing) if ASSET_LOADERS[key.type].should_reload != nil else false + + if force_no_reload || (existing.modtime == existing.fs_modtime && !wants_reload) { + result = .Cached + return existing.asset, existing.modtime, result + } else { + path := name.to_cstring(key.path) + new_modtime := physfs.getLastModTime(path) + // Try to load the new version + new_value, ok := ASSET_LOADERS[key.type].load(assetman, path, payload) + + if ok { + result = .Reloaded + ASSET_LOADERS[key.type].unload(existing.asset) + assetman.assets[key] = { + asset = new_value, + modtime = new_modtime, + fs_modtime = new_modtime, + } + + log.debugf("reloaded asset: %s", path) + + return new_value, new_modtime, result + } else { + log.warnf("failed to reload asset after modification %s", path) + result = .Cached + + return existing.asset, existing.modtime, result + } + } + } else { + path := name.to_cstring(key.path) + modtime = physfs.getLastModTime(path) + ok: bool + value, ok = ASSET_LOADERS[key.type].load(assetman, path, payload) + + if ok { + assetman.assets[key] = { + asset = value, + modtime = modtime, + fs_modtime = modtime, + } + result = .Loaded + + log.debugf("loaded asset: %s", path) + + return value, modtime, result + } else { + log.errorf("failed to load asset %s", path) + result = .Error + return {}, 0, .Error + } + } +} + +assetman_fetch_or_load :: proc( + assetman: ^Asset_Manager, + key: Asset_Key, + payload: Asset_Cache_Loader_Payload = nil, + force_no_reload := false, +) -> ( + value: Asset, + modtime: physfs.sint64, + result: Asset_Cache_Result, +) { + tracy.Zone() + value, modtime, result = assetman_fetch_or_load_internal( + assetman, + key, + payload, + force_no_reload, + ) + if result != .Cached { + log.debugf("asset {}: [{}] {}", key.type, name.to_string(key.path), result) + } + + if result == .Loaded { + modtime_watcher_add_asset(&assetman.watcher, key.type, key.path, modtime) + } + + return +} + +assetcache_destroy :: proc(ac: ^$T/Asset_Cache($E)) { + for _, v in ac.cache { + ac.loader.unload(v.value) + } + delete(ac.cache) +} + +get_texture :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Texture2D { + tracy.Zone() + + texture, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Texture}, + ) + + return texture.(rl.Texture2D) +} + +get_model_ex :: proc( + assetman: ^Asset_Manager, + path: cstring, + ref_modtime: physfs.sint64 = 0, // will check reload status using reference load time. When 0 reloaded will be true only if this call triggered reload +) -> ( + model: rl.Model, + modtime: physfs.sint64, + reloaded: bool, +) { + tracy.Zone() + + asset: Asset + result: Asset_Cache_Result + asset, modtime, result = assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Model}, + ) + model = asset.(rl.Model) + reloaded = result == .Reloaded || ref_modtime != modtime + + return +} + +get_model :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Model { + model, _, _ := get_model_ex(assetman, path) + + return model +} + +get_shader :: proc( + assetman: ^Asset_Manager, + vs_path: cstring, + ps_path: cstring, + location_set: Shader_Location_Set, +) -> Loaded_Shader { + asset, _, result := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(vs_path), type = .Shader}, + ps_path, + ) + loaded_shader := asset.(Loaded_Shader) + + if location_set > loaded_shader.location_set || result == .Loaded || result == .Reloaded { + loaded_shader.location_set = location_set + loaded_shader.locations = {} + + for location in location_set { + loaded_shader.locations[location] = rl.GetShaderLocation( + loaded_shader.shader, + SHADER_LOCATION_NAMES[location], + ) } } - return assetman.bvhs[path], should_recreate + return loaded_shader } -get_curve_1d :: proc(assetman: ^Asset_Manager, path: cstring) -> (curve: []f32) { - curve, _, _ = assetcache_fetch_or_load(&assetman.curves_1d, path) - return +get_sound :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Sound { + sound, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Sound}, + ) + return sound.(rl.Sound) +} + +get_music :: proc(assetman: ^Asset_Manager, path: cstring) -> rl.Music { + music, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Music}, + ) + return music.(rl.Music) +} + +get_bvh :: proc(assetman: ^Asset_Manager, path: name.Name) -> (Loaded_BVH, bool) { + tracy.Zone() + + asset, _, res := assetman_fetch_or_load(assetman, Asset_Key{path = path, type = .BVH}) + + return asset.(Loaded_BVH), res != Asset_Cache_Result.Error +} + +get_curve_1d :: proc(assetman: ^Asset_Manager, path: cstring) -> (curve: Curve_1D) { + asset, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Curve_1D}, + ) + return asset.(Curve_1D) } // Reads a two column comma separated csv file as a curve get_curve_2d :: proc(assetman: ^Asset_Manager, path: cstring) -> (curve: Curve_2D) { - curve, _, _ = assetcache_fetch_or_load(&assetman.curves_2d, path) - return + asset, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Curve_2D}, + ) + return asset.(Curve_2D) } // Reads a two column comma separated csv file as a curve @@ -575,421 +780,30 @@ get_scene_desc :: proc( scene: Scene_Desc, reloaded: bool, ) { - res: Asset_Cache_Result - scene, _, res = assetcache_fetch_or_load(&assetman.scenes, name.to_cstring(path)) - return scene, (res == .Loaded || res == .Reloaded) + asset, _, res := assetman_fetch_or_load( + assetman, + Asset_Key{path = path, type = .Scene}, + nil, + force_no_reload, + ) + return asset.(Scene_Desc), (res == .Loaded || res == .Reloaded) } get_convex :: proc(assetman: ^Asset_Manager, path: cstring) -> (result: Loaded_Convex) { - bytes, err := physfs.read_entire_file(string(path), context.temp_allocator) - if err != nil { - log.errorf("error reading file %v %s", err) - return - } - - Parse_Ctx :: struct { - bytes: []byte, - it: int, - line: int, - } - - advance :: proc(ctx: ^Parse_Ctx, by: int = 1) -> bool { - ctx.it = min(ctx.it + by, len(ctx.bytes) + 1) - return ctx.it < len(ctx.bytes) - } - - is_whitespace :: proc(b: byte) -> bool { - return b == ' ' || b == '\t' || b == '\r' || b == '\n' - } - - skip_line :: proc(ctx: ^Parse_Ctx) { - for ctx.it < len(ctx.bytes) && ctx.bytes[ctx.it] != '\n' { - advance(ctx) or_break - } - advance(ctx) - ctx.line += 1 - } - - skip_whitespase :: proc(ctx: ^Parse_Ctx) { - switch ctx.bytes[ctx.it] { - case ' ', '\t', '\r', '\n': - if ctx.bytes[ctx.it] == '\n' { - ctx.line += 1 - } - advance(ctx) or_break - case '#': - skip_line(ctx) - } - } - - Edge :: [2]u16 - edges_map := make_map(map[Edge]halfedge.Edge_Index, context.temp_allocator) - - edges := make_dynamic_array([dynamic]halfedge.Half_Edge, context.temp_allocator) - vertices := make_dynamic_array([dynamic]halfedge.Vertex, context.temp_allocator) - faces := make_dynamic_array([dynamic]halfedge.Face, context.temp_allocator) - min_pos, max_pos: rl.Vector3 = max(f32), min(f32) - - // Parse obj file directly into halfedge data structure - { - ctx := Parse_Ctx { - bytes = bytes, - line = 1, - } - - for ctx.it < len(ctx.bytes) { - skip_whitespase(&ctx) - switch ctx.bytes[ctx.it] { - case 'v': - // vertex - advance(&ctx) or_break - - vertex: rl.Vector3 - - coord_idx := 0 - for ctx.bytes[ctx.it] != '\n' && ctx.bytes[ctx.it] != '\r' { - skip_whitespase(&ctx) - s := string(ctx.bytes[ctx.it:]) - coord_val, nr, ok := strconv.parse_f32_prefix(s) - if !ok { - log.errorf( - "failed to parse float %v %s at line %d", - coord_idx, - ctx.bytes[ctx.it:][:12], - ctx.line, - ) - return - } - advance(&ctx, nr) or_break - - vertex[coord_idx] = coord_val - coord_idx += 1 - } - append(&vertices, halfedge.Vertex{pos = vertex, edge = -1}) - min_pos = lg.min(vertex, min_pos) - max_pos = lg.max(vertex, max_pos) - - if ctx.bytes[ctx.it] == '\r' { - advance(&ctx) - } - advance(&ctx) - ctx.line += 1 - case 'f': - advance(&ctx) or_break - - MAX_FACE_VERTS :: 10 - - indices_buf: [MAX_FACE_VERTS]u16 - index_count := 0 - - for ctx.bytes[ctx.it] != '\n' && ctx.bytes[ctx.it] != '\r' { - skip_whitespase(&ctx) - index_f, nr, ok := strconv.parse_f32_prefix(string(ctx.bytes[ctx.it:])) - if !ok { - log.errorf("failed to parse index at line %d", ctx.line) - return - } - advance(&ctx, nr) or_break - index := u16(index_f) - 1 - indices_buf[index_count] = u16(index) - index_count += 1 - } - if ctx.bytes[ctx.it] == '\r' { - advance(&ctx) - } - advance(&ctx) - ctx.line += 1 - - assert(index_count >= 3) - indices := indices_buf[:index_count] - - append(&faces, halfedge.Face{}) - face_idx := len(faces) - 1 - face := &faces[face_idx] - - first_edge_idx := len(edges) - - face.edge = halfedge.Edge_Index(first_edge_idx) - - plane: collision.Plane - { - i1, i2, i3 := indices[0], indices[1], indices[2] - v1, v2, v3 := vertices[i1].pos, vertices[i2].pos, vertices[i3].pos - - plane = collision.plane_from_point_normal( - v1, - lg.normalize0(lg.cross(v2 - v1, v3 - v1)), - ) - } - face.normal = plane.normal - - for index in indices[3:] { - assert( - abs(collision.signed_distance_plane(vertices[index].pos, plane)) < 0.01, - "mesh has non planar faces", - ) - } - - first_vert_pos := vertices[indices[0]].pos - - for i in 0 ..< len(indices) { - edge_idx := halfedge.Edge_Index(first_edge_idx + i) - prev_edge_relative := i == 0 ? len(indices) - 1 : i - 1 - next_edge_relative := (i + 1) % len(indices) - i1, i2 := indices[i], indices[next_edge_relative] - v1, v2 := &vertices[i1], &vertices[i2] - - assert( - lg.dot( - lg.cross(v1.pos - first_vert_pos, v2.pos - first_vert_pos), - plane.normal, - ) >= - 0, - "non convex face or non ccw winding", - ) - - if v1.edge == -1 { - v1.edge = edge_idx - } - - edge := halfedge.Half_Edge { - origin = halfedge.Vertex_Index(i1), - face = halfedge.Face_Index(face_idx), - twin = -1, - next = halfedge.Edge_Index(first_edge_idx + next_edge_relative), - prev = halfedge.Edge_Index(first_edge_idx + prev_edge_relative), - } - - stable_index := [2]u16{min(i1, i2), max(i1, i2)} - if stable_index in edges_map { - edge.twin = edges_map[stable_index] - twin_edge := &edges[edge.twin] - assert(twin_edge.twin == -1, "edge has more than two faces attached") - twin_edge.twin = edge_idx - } else { - edges_map[stable_index] = edge_idx - } - - append(&edges, edge) - } - case: - skip_line(&ctx) - } - } - } - - center := (max_pos + min_pos) * 0.5 - extent := (max_pos - min_pos) * 0.5 - - center_of_mass: rl.Vector3 - - mesh := halfedge.Half_Edge_Mesh { - vertices = vertices[:], - edges = edges[:], - faces = faces[:], - center = center, - extent = extent, - } - - // Center of mass calculation - total_volume := f32(0.0) - { - rlgl.Begin(rlgl.TRIANGLES) - rlgl.End() - - rlgl.EnableWireMode() - defer rlgl.DisableWireMode() - - tri_idx := 0 - for face_idx in 0 ..< len(faces) { - face := faces[face_idx] - // for all triangles - it := halfedge.iterator_face_edges(mesh, halfedge.Face_Index(face_idx)) - i := 0 - tri: [3]rl.Vector3 - for edge in halfedge.iterate_next_edge(&it) { - switch i { - case 0 ..< 3: - tri[i] = mesh.vertices[edge.origin].pos - case: - tri[1] = tri[2] - tri[2] = mesh.vertices[edge.origin].pos - } - - if i >= 2 { - plane := collision.plane_from_point_normal(tri[0], -face.normal) - - h := max(0, collision.signed_distance_plane(center, plane)) - tri_area := - lg.dot(lg.cross(tri[1] - tri[0], tri[2] - tri[0]), face.normal) * 0.5 - tetra_volume := 1.0 / 3.0 * tri_area * h - total_volume += tetra_volume - - tetra_centroid := (tri[0] + tri[1] + tri[2] + center) * 0.25 - center_of_mass += tetra_volume * tetra_centroid - - tri_idx += 1 - } - - i += 1 - } - } - } - - assert(total_volume > 0, "degenerate convex hull") - center_of_mass /= total_volume - - inertia_tensor: lg.Matrix3f32 - // Find inertia tensor - { - tri_idx := 0 - for face_idx in 0 ..< len(faces) { - // for all triangles - it := halfedge.iterator_face_edges(mesh, halfedge.Face_Index(face_idx)) - i := 0 - tri: [3]rl.Vector3 - for edge in halfedge.iterate_next_edge(&it) { - switch i { - case 0 ..< 3: - tri[i] = mesh.vertices[edge.origin].pos - case: - tri[1] = tri[2] - tri[2] = mesh.vertices[edge.origin].pos - } - - if i >= 2 { - tet := Tetrahedron { - p = {tri[0], tri[1], tri[2], center_of_mass}, - } - - inertia_tensor += tetrahedron_inertia_tensor(tet, center_of_mass) - - tri_idx += 1 - } - - i += 1 - } - } - } - inertia_tensor = inertia_tensor - - return { - mesh = mesh, - center_of_mass = center_of_mass, - inertia_tensor = inertia_tensor, - total_volume = total_volume, - } -} - -// TODO: move convex stuff out of assets.odin -Tetrahedron :: struct { - p: [4]rl.Vector3, -} - -tetrahedron_volume :: #force_inline proc(tet: Tetrahedron) -> f32 { - return( - 1.0 / - 6.0 * - abs(lg.dot(lg.cross(tet.p[1] - tet.p[0], tet.p[2] - tet.p[0]), tet.p[3] - tet.p[0])) \ + asset, _, _ := assetman_fetch_or_load( + assetman, + Asset_Key{path = name.from_cstring(path), type = .Convex}, ) -} - -square :: #force_inline proc(val: f32) -> f32 { - return val * val -} - -tetrahedron_inertia_tensor :: proc(tet: Tetrahedron, o: rl.Vector3) -> lg.Matrix3f32 { - p1, p2, p3, p4 := tet.p[0] - o, tet.p[1] - o, tet.p[2] - o, tet.p[3] - o - // Jacobian determinant is 6*Volume - det_j := abs(6.0 * tetrahedron_volume(tet)) - - moment_of_inertia_term :: proc(p1, p2, p3, p4: rl.Vector3, axis: int) -> f32 { - return( - square(p1[axis]) + - p1[axis] * p2[axis] + - square(p2[axis]) + - p1[axis] * p3[axis] + - p2[axis] * p3[axis] + - square(p3[axis]) + - p1[axis] * p4[axis] + - p2[axis] * p4[axis] + - p3[axis] * p4[axis] + - square(p4[axis]) \ - ) - } - - product_of_inertia_term :: proc(p1, p2, p3, p4: rl.Vector3, axis1, axis2: int) -> f32 { - return( - 2.0 * p1[axis1] * p1[axis2] + - p2[axis1] * p1[axis2] + - p3[axis1] * p1[axis2] + - p4[axis1] * p1[axis2] + - p1[axis1] * p2[axis2] + - 2.0 * p2[axis1] * p2[axis2] + - p3[axis1] * p2[axis2] + - p4[axis1] * p2[axis2] + - p1[axis1] * p3[axis2] + - p2[axis1] * p3[axis2] + - 2.0 * p3[axis1] * p3[axis2] + - p4[axis1] * p3[axis2] + - p1[axis1] * p4[axis2] + - p2[axis1] * p4[axis2] + - p3[axis1] * p4[axis2] + - 2.0 * p4[axis1] * p4[axis2] \ - ) - } - - MOMENT_OF_INERTIA_DENOM :: 1.0 / 60.0 - PRODUCT_OF_INERTIA_DENOM :: 1.0 / 120.0 - - x_term := moment_of_inertia_term(p1, p2, p3, p4, 0) - y_term := moment_of_inertia_term(p1, p2, p3, p4, 1) - z_term := moment_of_inertia_term(p1, p2, p3, p4, 2) - - // Moments of intertia with respect to XYZ - // Integral(y^2 + z^2) - a := det_j * (y_term + z_term) * MOMENT_OF_INERTIA_DENOM - // Integral(x^2 + z^2) - b := det_j * (x_term + z_term) * MOMENT_OF_INERTIA_DENOM - // Integral(x^2 + y^2) - c := det_j * (x_term + y_term) * MOMENT_OF_INERTIA_DENOM - - // Products of inertia - a_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 1, axis2 = 2) * PRODUCT_OF_INERTIA_DENOM - b_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 0, axis2 = 2) * PRODUCT_OF_INERTIA_DENOM - c_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 0, axis2 = 1) * PRODUCT_OF_INERTIA_DENOM - - return {a, -b_, -c_, -b_, b, -a_, -c_, -a_, c} -} - -debug_draw_tetrahedron_wires :: proc(tri: [3]rl.Vector3, p: rl.Vector3, color: rl.Color) { - rlgl.Begin(rlgl.LINES) - defer rlgl.End() - - debug.rlgl_color(color) - - debug.rlgl_vertex3v2(tri[0], tri[1]) - debug.rlgl_vertex3v2(tri[1], tri[2]) - debug.rlgl_vertex3v2(tri[2], tri[0]) - debug.rlgl_vertex3v2(tri[0], p) - debug.rlgl_vertex3v2(tri[1], p) - debug.rlgl_vertex3v2(tri[2], p) + return asset.(Loaded_Convex) } shutdown :: proc(assetman: ^Asset_Manager) { tracy.Zone() - assetcache_destroy(&assetman.textures) - assetcache_destroy(&assetman.models) - assetcache_destroy(&assetman.shaders) - assetcache_destroy(&assetman.sounds) - assetcache_destroy(&assetman.music) - assetcache_destroy(&assetman.curves_1d) - assetcache_destroy(&assetman.curves_2d) - assetcache_destroy(&assetman.scenes) + modtime_watcher_deinit(&assetman.watcher) - for _, &loaded_bvh in assetman.bvhs { - destroy_loaded_bvh(&loaded_bvh) + for k, v in assetman.assets { + ASSET_LOADERS[k.type].unload(v.asset) } - delete(assetman.bvhs) + delete_map(assetman.assets) } diff --git a/game/assets/parsers.odin b/game/assets/parsers.odin index a1fabad..7bbac22 100644 --- a/game/assets/parsers.odin +++ b/game/assets/parsers.odin @@ -4,7 +4,13 @@ import "core:bytes" import "core:encoding/csv" import "core:io" import "core:log" +import lg "core:math/linalg" import "core:strconv" +import "game:debug" +import "game:halfedge" +import "game:physics/collision" +import rl "libs:raylib" +import rlgl "libs:raylib/rlgl" CSV_Parse_Error :: enum { Ok, @@ -69,7 +75,7 @@ parse_csv_2d :: proc( data: []byte, allocator := context.allocator, ) -> ( - curve: Loaded_Curve_2D, + curve: Curve_2D, error: CSV_Parse_Error, ) { bytes_reader: bytes.Reader @@ -125,8 +131,400 @@ parse_csv_2d :: proc( append(&tmp_result, [2]f32{f32(key), f32(val)}) } - curve.points = make([][2]f32, len(tmp_result), allocator) - copy(curve.points, tmp_result[:]) + curve = make([][2]f32, len(tmp_result), allocator) + copy(curve, tmp_result[:]) return } + +parse_convex :: proc(bytes: []byte, allocator := context.allocator) -> (Loaded_Convex, bool) { + Parse_Ctx :: struct { + bytes: []byte, + it: int, + line: int, + } + + advance :: proc(ctx: ^Parse_Ctx, by: int = 1) -> bool { + ctx.it = min(ctx.it + by, len(ctx.bytes) + 1) + return ctx.it < len(ctx.bytes) + } + + is_whitespace :: proc(b: byte) -> bool { + return b == ' ' || b == '\t' || b == '\r' || b == '\n' + } + + skip_line :: proc(ctx: ^Parse_Ctx) { + for ctx.it < len(ctx.bytes) && ctx.bytes[ctx.it] != '\n' { + advance(ctx) or_break + } + advance(ctx) + ctx.line += 1 + } + + skip_whitespase :: proc(ctx: ^Parse_Ctx) { + switch ctx.bytes[ctx.it] { + case ' ', '\t', '\r', '\n': + if ctx.bytes[ctx.it] == '\n' { + ctx.line += 1 + } + advance(ctx) or_break + case '#': + skip_line(ctx) + } + } + + Edge :: [2]u16 + edges_map := make_map(map[Edge]halfedge.Edge_Index, context.temp_allocator) + + edges := make_dynamic_array([dynamic]halfedge.Half_Edge, context.temp_allocator) + vertices := make_dynamic_array([dynamic]halfedge.Vertex, context.temp_allocator) + faces := make_dynamic_array([dynamic]halfedge.Face, context.temp_allocator) + min_pos, max_pos: rl.Vector3 = max(f32), min(f32) + + // Parse obj file directly into halfedge data structure + { + ctx := Parse_Ctx { + bytes = bytes, + line = 1, + } + + for ctx.it < len(ctx.bytes) { + skip_whitespase(&ctx) + switch ctx.bytes[ctx.it] { + case 'v': + // vertex + advance(&ctx) or_break + + vertex: rl.Vector3 + + coord_idx := 0 + for ctx.bytes[ctx.it] != '\n' && ctx.bytes[ctx.it] != '\r' { + skip_whitespase(&ctx) + s := string(ctx.bytes[ctx.it:]) + coord_val, nr, ok := strconv.parse_f32_prefix(s) + if !ok { + log.errorf( + "failed to parse float %v %s at line %d", + coord_idx, + ctx.bytes[ctx.it:][:12], + ctx.line, + ) + return {}, false + } + advance(&ctx, nr) or_break + + vertex[coord_idx] = coord_val + coord_idx += 1 + } + append(&vertices, halfedge.Vertex{pos = vertex, edge = -1}) + min_pos = lg.min(vertex, min_pos) + max_pos = lg.max(vertex, max_pos) + + if ctx.bytes[ctx.it] == '\r' { + advance(&ctx) + } + advance(&ctx) + ctx.line += 1 + case 'f': + advance(&ctx) or_break + + MAX_FACE_VERTS :: 10 + + indices_buf: [MAX_FACE_VERTS]u16 + index_count := 0 + + for ctx.bytes[ctx.it] != '\n' && ctx.bytes[ctx.it] != '\r' { + skip_whitespase(&ctx) + index_f, nr, ok := strconv.parse_f32_prefix(string(ctx.bytes[ctx.it:])) + if !ok { + log.errorf("failed to parse index at line %d", ctx.line) + return {}, false + } + advance(&ctx, nr) or_break + index := u16(index_f) - 1 + indices_buf[index_count] = u16(index) + index_count += 1 + } + if ctx.bytes[ctx.it] == '\r' { + advance(&ctx) + } + advance(&ctx) + ctx.line += 1 + + assert(index_count >= 3) + indices := indices_buf[:index_count] + + append(&faces, halfedge.Face{}) + face_idx := len(faces) - 1 + face := &faces[face_idx] + + first_edge_idx := len(edges) + + face.edge = halfedge.Edge_Index(first_edge_idx) + + plane: collision.Plane + { + i1, i2, i3 := indices[0], indices[1], indices[2] + v1, v2, v3 := vertices[i1].pos, vertices[i2].pos, vertices[i3].pos + + plane = collision.plane_from_point_normal( + v1, + lg.normalize0(lg.cross(v2 - v1, v3 - v1)), + ) + } + face.normal = plane.normal + + for index in indices[3:] { + assert( + abs(collision.signed_distance_plane(vertices[index].pos, plane)) < 0.01, + "mesh has non planar faces", + ) + } + + first_vert_pos := vertices[indices[0]].pos + + for i in 0 ..< len(indices) { + edge_idx := halfedge.Edge_Index(first_edge_idx + i) + prev_edge_relative := i == 0 ? len(indices) - 1 : i - 1 + next_edge_relative := (i + 1) % len(indices) + i1, i2 := indices[i], indices[next_edge_relative] + v1, v2 := &vertices[i1], &vertices[i2] + + assert( + lg.dot( + lg.cross(v1.pos - first_vert_pos, v2.pos - first_vert_pos), + plane.normal, + ) >= + 0, + "non convex face or non ccw winding", + ) + + if v1.edge == -1 { + v1.edge = edge_idx + } + + edge := halfedge.Half_Edge { + origin = halfedge.Vertex_Index(i1), + face = halfedge.Face_Index(face_idx), + twin = -1, + next = halfedge.Edge_Index(first_edge_idx + next_edge_relative), + prev = halfedge.Edge_Index(first_edge_idx + prev_edge_relative), + } + + stable_index := [2]u16{min(i1, i2), max(i1, i2)} + if stable_index in edges_map { + edge.twin = edges_map[stable_index] + twin_edge := &edges[edge.twin] + assert(twin_edge.twin == -1, "edge has more than two faces attached") + twin_edge.twin = edge_idx + } else { + edges_map[stable_index] = edge_idx + } + + append(&edges, edge) + } + case: + skip_line(&ctx) + } + } + } + + center := (max_pos + min_pos) * 0.5 + extent := (max_pos - min_pos) * 0.5 + + center_of_mass: rl.Vector3 + + final_vertices := make([]halfedge.Vertex, len(vertices), allocator) + final_edges := make([]halfedge.Half_Edge, len(edges), allocator) + final_faces := make([]halfedge.Face, len(faces), allocator) + copy(final_vertices, vertices[:]) + copy(final_edges, edges[:]) + copy(final_faces, faces[:]) + + mesh := halfedge.Half_Edge_Mesh { + vertices = final_vertices, + edges = final_edges, + faces = final_faces, + center = center, + extent = extent, + } + + // Center of mass calculation + total_volume := f32(0.0) + { + tri_idx := 0 + for face_idx in 0 ..< len(faces) { + face := faces[face_idx] + // for all triangles + it := halfedge.iterator_face_edges(mesh, halfedge.Face_Index(face_idx)) + i := 0 + tri: [3]rl.Vector3 + for edge in halfedge.iterate_next_edge(&it) { + switch i { + case 0 ..< 3: + tri[i] = mesh.vertices[edge.origin].pos + case: + tri[1] = tri[2] + tri[2] = mesh.vertices[edge.origin].pos + } + + if i >= 2 { + plane := collision.plane_from_point_normal(tri[0], -face.normal) + + h := max(0, collision.signed_distance_plane(center, plane)) + tri_area := + lg.dot(lg.cross(tri[1] - tri[0], tri[2] - tri[0]), face.normal) * 0.5 + tetra_volume := 1.0 / 3.0 * tri_area * h + total_volume += tetra_volume + + tetra_centroid := (tri[0] + tri[1] + tri[2] + center) * 0.25 + center_of_mass += tetra_volume * tetra_centroid + + tri_idx += 1 + } + + i += 1 + } + } + } + + assert(total_volume > 0, "degenerate convex hull") + center_of_mass /= total_volume + + inertia_tensor: lg.Matrix3f32 + // Find inertia tensor + { + tri_idx := 0 + for face_idx in 0 ..< len(faces) { + // for all triangles + it := halfedge.iterator_face_edges(mesh, halfedge.Face_Index(face_idx)) + i := 0 + tri: [3]rl.Vector3 + for edge in halfedge.iterate_next_edge(&it) { + switch i { + case 0 ..< 3: + tri[i] = mesh.vertices[edge.origin].pos + case: + tri[1] = tri[2] + tri[2] = mesh.vertices[edge.origin].pos + } + + if i >= 2 { + tet := Tetrahedron { + p = {tri[0], tri[1], tri[2], center_of_mass}, + } + + inertia_tensor += tetrahedron_inertia_tensor(tet, center_of_mass) + + tri_idx += 1 + } + + i += 1 + } + } + } + inertia_tensor = inertia_tensor + + return Loaded_Convex { + mesh = mesh, + center_of_mass = center_of_mass, + inertia_tensor = inertia_tensor, + total_volume = total_volume, + }, + true +} + +// TODO: move convex stuff out of assets.odin +Tetrahedron :: struct { + p: [4]rl.Vector3, +} + +tetrahedron_volume :: #force_inline proc(tet: Tetrahedron) -> f32 { + return( + 1.0 / + 6.0 * + abs(lg.dot(lg.cross(tet.p[1] - tet.p[0], tet.p[2] - tet.p[0]), tet.p[3] - tet.p[0])) \ + ) +} + +square :: #force_inline proc(val: f32) -> f32 { + return val * val +} + +tetrahedron_inertia_tensor :: proc(tet: Tetrahedron, o: rl.Vector3) -> lg.Matrix3f32 { + p1, p2, p3, p4 := tet.p[0] - o, tet.p[1] - o, tet.p[2] - o, tet.p[3] - o + // Jacobian determinant is 6*Volume + det_j := abs(6.0 * tetrahedron_volume(tet)) + + moment_of_inertia_term :: proc(p1, p2, p3, p4: rl.Vector3, axis: int) -> f32 { + return( + square(p1[axis]) + + p1[axis] * p2[axis] + + square(p2[axis]) + + p1[axis] * p3[axis] + + p2[axis] * p3[axis] + + square(p3[axis]) + + p1[axis] * p4[axis] + + p2[axis] * p4[axis] + + p3[axis] * p4[axis] + + square(p4[axis]) \ + ) + } + + product_of_inertia_term :: proc(p1, p2, p3, p4: rl.Vector3, axis1, axis2: int) -> f32 { + return( + 2.0 * p1[axis1] * p1[axis2] + + p2[axis1] * p1[axis2] + + p3[axis1] * p1[axis2] + + p4[axis1] * p1[axis2] + + p1[axis1] * p2[axis2] + + 2.0 * p2[axis1] * p2[axis2] + + p3[axis1] * p2[axis2] + + p4[axis1] * p2[axis2] + + p1[axis1] * p3[axis2] + + p2[axis1] * p3[axis2] + + 2.0 * p3[axis1] * p3[axis2] + + p4[axis1] * p3[axis2] + + p1[axis1] * p4[axis2] + + p2[axis1] * p4[axis2] + + p3[axis1] * p4[axis2] + + 2.0 * p4[axis1] * p4[axis2] \ + ) + } + + MOMENT_OF_INERTIA_DENOM :: 1.0 / 60.0 + PRODUCT_OF_INERTIA_DENOM :: 1.0 / 120.0 + + x_term := moment_of_inertia_term(p1, p2, p3, p4, 0) + y_term := moment_of_inertia_term(p1, p2, p3, p4, 1) + z_term := moment_of_inertia_term(p1, p2, p3, p4, 2) + + // Moments of intertia with respect to XYZ + // Integral(y^2 + z^2) + a := det_j * (y_term + z_term) * MOMENT_OF_INERTIA_DENOM + // Integral(x^2 + z^2) + b := det_j * (x_term + z_term) * MOMENT_OF_INERTIA_DENOM + // Integral(x^2 + y^2) + c := det_j * (x_term + y_term) * MOMENT_OF_INERTIA_DENOM + + // Products of inertia + a_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 1, axis2 = 2) * PRODUCT_OF_INERTIA_DENOM + b_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 0, axis2 = 2) * PRODUCT_OF_INERTIA_DENOM + c_ := product_of_inertia_term(p1, p2, p3, p4, axis1 = 0, axis2 = 1) * PRODUCT_OF_INERTIA_DENOM + + return {a, -b_, -c_, -b_, b, -a_, -c_, -a_, c} +} + +debug_draw_tetrahedron_wires :: proc(tri: [3]rl.Vector3, p: rl.Vector3, color: rl.Color) { + rlgl.Begin(rlgl.LINES) + defer rlgl.End() + + debug.rlgl_color(color) + + debug.rlgl_vertex3v2(tri[0], tri[1]) + debug.rlgl_vertex3v2(tri[1], tri[2]) + debug.rlgl_vertex3v2(tri[2], tri[0]) + debug.rlgl_vertex3v2(tri[0], p) + debug.rlgl_vertex3v2(tri[1], p) + debug.rlgl_vertex3v2(tri[2], p) +} diff --git a/game/assets/watcher.odin b/game/assets/watcher.odin new file mode 100644 index 0000000..036deba --- /dev/null +++ b/game/assets/watcher.odin @@ -0,0 +1,145 @@ +package assets + +import "base:runtime" +import "common:name" +import "core:log" +import "core:sync/chan" +import "core:thread" +import "libs:physfs" + +ASSET_WATCHER_OPS_BUFFER :: 256 + +// Add asset to watch list +Asset_Watcher_Op_Add :: struct { + type: Asset_Type, + path: name.Name, + modtime: physfs.sint64, +} +// Remove asset from watch list +Asset_Watcher_Op_Remove :: struct { + type: Asset_Type, + path: name.Name, +} + +Asset_Watcher_Op :: union #no_nil { + Asset_Watcher_Op_Add, + Asset_Watcher_Op_Remove, +} + +Watcher_Asset :: struct { + type: Asset_Type, + path: name.Name, + modtime: physfs.sint64, +} + +Asset_Modtime_Watcher :: struct { + ops: chan.Chan(Asset_Watcher_Op), + modified_assets: chan.Chan(Watcher_Asset), + loaded_assets: [dynamic]Watcher_Asset, + thread: ^thread.Thread, +} + +modtime_watcher_init :: proc(watcher: ^Asset_Modtime_Watcher, allocator := context.allocator) { + err: runtime.Allocator_Error + watcher.ops, err = chan.create_buffered( + chan.Chan(Asset_Watcher_Op), + ASSET_WATCHER_OPS_BUFFER, + allocator, + ) + assert(err == nil) + watcher.modified_assets, err = chan.create_buffered( + chan.Chan(Watcher_Asset), + ASSET_WATCHER_OPS_BUFFER, + allocator, + ) + watcher.loaded_assets = make_dynamic_array([dynamic]Watcher_Asset, allocator) + + watcher.thread = thread.create(modtime_watcher_thread_proc) + watcher.thread.data = watcher + watcher_context := runtime.default_context() + watcher_context.logger = context.logger + watcher_context.allocator = context.allocator + watcher.thread.init_context = watcher_context + thread.start(watcher.thread) +} + +modtime_watcher_deinit :: proc(watcher: ^Asset_Modtime_Watcher) { + if !chan.is_closed(&watcher.ops) { + chan.close(&watcher.ops) + thread.join(watcher.thread) + watcher.thread = nil + } + + chan.destroy(&watcher.ops) + chan.close(&watcher.modified_assets) + chan.destroy(&watcher.modified_assets) + delete(watcher.loaded_assets) +} + +@(private = "file") +modtime_watcher_thread_proc :: proc(t: ^thread.Thread) { + watcher := cast(^Asset_Modtime_Watcher)t.data + + log.debugf("watcher thread") + + for !chan.is_closed(&watcher.ops) { + for recv_op in chan.try_recv(watcher.ops) { + switch op in recv_op { + case Asset_Watcher_Op_Add: + log.debugf("add [{}] {}", op.type, name.to_string(op.path)) + append( + &watcher.loaded_assets, + Watcher_Asset{type = op.type, path = op.path, modtime = op.modtime}, + ) + case Asset_Watcher_Op_Remove: + log.debugf("remove [{}] {}", op.type, name.to_string(op.path)) + i := 0 + for i < len(watcher.loaded_assets) { + if op.path == watcher.loaded_assets[i].path && + op.type == watcher.loaded_assets[i].type { + unordered_remove(&watcher.loaded_assets, i) + } else { + i += 1 + } + } + } + } + + for &asset in watcher.loaded_assets { + modtime := physfs.getLastModTime(name.to_cstring(asset.path)) + + if asset.modtime != modtime { + log.debugf("change [{}] {}", asset.type, name.to_string(asset.path)) + ok := chan.send( + watcher.modified_assets, + Watcher_Asset{type = asset.type, path = asset.path, modtime = modtime}, + ) + assert(ok) + } + asset.modtime = modtime + } + + // To avoid busy loop just in case + thread.yield() + } +} + +modtime_watcher_add_asset :: proc( + watcher: ^Asset_Modtime_Watcher, + type: Asset_Type, + path: name.Name, + modtime: physfs.sint64, +) -> bool { + return chan.send( + watcher.ops, + Asset_Watcher_Op_Add{type = type, path = path, modtime = modtime}, + ) +} + +modtime_watcher_remove_asset :: proc( + watcher: ^Asset_Modtime_Watcher, + type: Asset_Type, + path: name.Name, +) -> bool { + return chan.send(watcher.ops, Asset_Watcher_Op_Remove{type = type, path = path}) +} diff --git a/game/game.odin b/game/game.odin index 4989782..00f7f89 100644 --- a/game/game.odin +++ b/game/game.odin @@ -63,7 +63,8 @@ scene_destroy :: proc(world: ^World, scene: ^Scene) { } immediate_scene :: proc(world: ^World, scene: ^Scene, path: cstring) { - path_name := name.from_string(string(path)) + tracy.Zone() + path_name := name.from_cstring(path) desc, reloaded := assets.get_scene_desc(&g_mem.assetman, path_name) @@ -71,15 +72,16 @@ immediate_scene :: proc(world: ^World, scene: ^Scene, path: cstring) { scene_destroy(world, scene) scene.scene_desc_path = path_name + scene.level_geoms = make([]physics.Level_Geom_Handle, len(desc.instances)) sim_state := physics.get_sim_state(&world.physics_scene) - for inst in desc.instances { - physics.add_level_geom( + for inst, i in desc.instances { + scene.level_geoms[i] = physics.add_level_geom( sim_state, physics.Level_Geom_Config { position = inst.pos, rotation = inst.rot, - source = physics.Level_Geometry_Asset(name.to_string(inst.model)), + source = physics.Level_Geometry_Asset(inst.model), }, ) } @@ -87,6 +89,7 @@ immediate_scene :: proc(world: ^World, scene: ^Scene, path: cstring) { } scene_copy :: proc(dst, src: ^Scene) { + tracy.Zone() dst.scene_desc_path = src.scene_desc_path if len(dst.level_geoms) != len(src.level_geoms) { delete(dst.level_geoms) @@ -101,7 +104,7 @@ scene_draw :: proc(scene: ^Scene) { render.draw_model( assets.get_model(&g_mem.assetman, name.to_cstring(geo.model)), {}, - auto_cast linalg.matrix4_from_trs(geo.pos, geo.rot, geo.scale), + auto_cast linalg.matrix4_from_trs(geo.pos, geo.rot, 1), ) } } @@ -1437,6 +1440,8 @@ game_update :: proc() -> bool { tracy.Zone() defer tracy.FrameMark() + assets.assetman_tick(&g_mem.assetman) + update() draw() @@ -1474,7 +1479,6 @@ game_init :: proc() { init_physifs_raylib_callbacks() assets.assetman_init(&g_mem.assetman) - assets.init(&g_mem.assetman) editor_state_init(&g_mem.es, 100) runtime_world_init(&g_mem.runtime_world, DEV_BUILD ? 100 : 2) diff --git a/game/physics/collision/convex.odin b/game/physics/collision/convex.odin index a38b04f..ffb76c4 100644 --- a/game/physics/collision/convex.odin +++ b/game/physics/collision/convex.odin @@ -265,8 +265,7 @@ query_separation_edges :: proc( a_edge = -1 b_edge = -1 - temp := runtime.default_temp_allocator_temp_begin() - defer runtime.default_temp_allocator_temp_end(temp) + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() checked_pairs: bit_array.Bit_Array bit_array.init(&checked_pairs, len(a.edges) * len(b.edges), 0, context.temp_allocator) diff --git a/game/physics/debug.odin b/game/physics/debug.odin index 766bc60..f5a4d42 100644 --- a/game/physics/debug.odin +++ b/game/physics/debug.odin @@ -1,5 +1,6 @@ package physics +import "base:runtime" import "bvh" import "common:name" import "core:fmt" @@ -9,6 +10,7 @@ import lg "core:math/linalg" import "core:mem" import "core:slice" import "core:strings" +import "game:assets" import "game:debug" import he "game:halfedge" import "game:ui" @@ -61,7 +63,14 @@ init_debug_state :: proc(debug_state: ^Debug_State) { draw_debug_scene :: proc(scene: ^Scene, debug_state: ^Debug_State) { tracy.Zone() + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + sim_state := get_sim_state(scene) + sim_cache: Sim_Cache + sim_cache.level_geom_asset_bvh = make_map( + map[Level_Geom_Handle]assets.Loaded_BVH, + context.temp_allocator, + ) // Static_TLAS if true && sim_state.static_tlas.built { @@ -73,22 +82,27 @@ draw_debug_scene :: proc(scene: ^Scene, debug_state: ^Debug_State) { it := bvh.iterator(&sim_state.static_tlas.bvh_tree) - for node in bvh.iterator_next(&it) { - if bvh.is_leaf_node(node) { - prim_start := node.child_or_prim_start + if false { + for node in bvh.iterator_next(&it) { + if bvh.is_leaf_node(node) { + prim_start := node.child_or_prim_start - for level_geom_idx in prim_start ..< prim_start + node.prim_len { - level_geom_handle := index_to_level_geom(int(level_geom_idx)) - level_geom := get_level_geom(sim_state, level_geom_handle) - blas := get_level_geom_blas(sim_state, level_geom_handle) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + for level_geom_idx in prim_start ..< prim_start + node.prim_len { + level_geom_handle := index_to_level_geom(int(level_geom_idx)) + level_geom := get_level_geom(sim_state, level_geom_handle) + blas, vertices, indices := get_level_geom_data( + sim_state, + &sim_cache, + level_geom_handle, + ) - bvh.debug_draw_bvh_bounds_mesh( - &blas, - bvh.Mesh{vertices = vertices, indices = indices}, - level_geom.x, - 0, - ) + bvh.debug_draw_bvh_bounds_mesh( + &blas, + bvh.Mesh{vertices = vertices, indices = indices}, + level_geom.x, + 0, + ) + } } } } diff --git a/game/physics/helpers.odin b/game/physics/helpers.odin index 3f4c26e..480d89d 100644 --- a/game/physics/helpers.odin +++ b/game/physics/helpers.odin @@ -300,6 +300,7 @@ body_get_convex_shapes_world :: proc( level_geom_get_convex_shape :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, level_geom_handle: Level_Geom_Handle, tri_idx: int, allocator := context.temp_allocator, @@ -307,7 +308,7 @@ level_geom_get_convex_shape :: proc( mesh: collision.Convex, ) { level_geom := get_level_geom(sim_state, level_geom_handle) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + _, vertices, indices := get_level_geom_data(sim_state, sim_cache, level_geom_handle) return collision.double_sided_triangle_to_convex( get_transformed_triangle(vertices, indices, tri_idx, level_geom.x, level_geom.q), allocator, @@ -353,7 +354,7 @@ rotate_extent :: proc(extent: Vec3, q: Quat) -> Vec3 { return result } -aabb_transform :: proc(local_aabb: AABB, x: Vec3, q: Quat) -> (aabb: AABB) { +aabb_transform_phys :: proc(local_aabb: AABB, x: Vec3, q: Quat) -> (aabb: AABB) { aabb.center = lg.quaternion_mul_vector3(q, local_aabb.center) + x aabb.extent = rotate_extent(local_aabb.extent, q) @@ -361,6 +362,34 @@ aabb_transform :: proc(local_aabb: AABB, x: Vec3, q: Quat) -> (aabb: AABB) { return } +// TODO: consolidate formats, please +aabb_transform_bvh :: proc(local_aabb: bvh.AABB, x: Vec3, q: Quat) -> (aabb: bvh.AABB) { + phys_aabb := bvh_aabb_to_phys_aabb(local_aabb) + phys_aabb = aabb_transform(phys_aabb, x, q) + + aabb.min = phys_aabb.center - phys_aabb.extent + aabb.max = phys_aabb.center + phys_aabb.extent + + return +} + +aabb_transform :: proc { + aabb_transform_phys, + aabb_transform_bvh, +} + +aabb_inv_transform :: proc(local_aabb: bvh.AABB, x: Vec3, q: Quat) -> (aabb: bvh.AABB) { + phys_aabb := bvh_aabb_to_phys_aabb(local_aabb) + inv_q := lg.quaternion_inverse(q) + phys_aabb.center = lg.quaternion_mul_vector3(inv_q, phys_aabb.center - x) + phys_aabb.extent = rotate_extent(phys_aabb.extent, inv_q) + + aabb.min = phys_aabb.center - phys_aabb.extent + aabb.max = phys_aabb.center + phys_aabb.extent + + return +} + input_shape_get_aabb :: proc(shapes: []Input_Shape) -> (aabb: AABB) { min, max: Vec3 = max(f32), min(f32) diff --git a/game/physics/scene.odin b/game/physics/scene.odin index 624b942..ee2b66c 100644 --- a/game/physics/scene.odin +++ b/game/physics/scene.odin @@ -4,7 +4,6 @@ import "bvh" import "collision" import "common:name" import lg "core:math/linalg" -import "core:strings" import "game:assets" import "game:container/spanpool" import "libs:tracy" @@ -476,9 +475,6 @@ Suspension_Constraint_Ptr :: #soa^#soa[]Suspension_Constraint Engine_Ptr :: ^Engine Level_Geom_Ptr :: ^Level_Geom -_invalid_body: #soa[1]Body -_invalid_body_slice := _invalid_body[:] - _invalid_suspension_constraint: #soa[1]Suspension_Constraint _invalid_suspension_constraint_slice := _invalid_suspension_constraint[:] @@ -507,8 +503,12 @@ flip_sim_state :: proc(scene: ^Scene) { /// Returns pointer to soa slice. NEVER STORE IT get_body :: proc(sim_state: ^Sim_State, handle: Body_Handle) -> Body_Ptr { + @(static) _invalid_body: #soa[1]Body + @(static) _invalid_body_slice: #soa[]Body + index := int(handle) - 1 if index < 0 || index >= len(sim_state.bodies_slice) { + _invalid_body_slice = _invalid_body[:] _invalid_body_slice[0] = { alive = true, q = lg.QUATERNIONF32_IDENTITY, @@ -602,7 +602,7 @@ Engine_Config :: struct { axle: Drive_Axle_Config, } -Level_Geometry_Asset :: distinct string +Level_Geometry_Asset :: distinct name.Name Level_Geometry_Mesh :: struct { vertices: []Vec3, @@ -949,8 +949,10 @@ get_level_geom :: proc(sim_state: ^Sim_State, handle: Level_Geom_Handle) -> Leve get_level_geom_data :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, handle: Level_Geom_Handle, ) -> ( + blas: bvh.BVH, vertices: []Vec3, indices: []u16, ) { @@ -958,17 +960,28 @@ get_level_geom_data :: proc( switch s in level_geom.source { case Level_Geom_Source_Local: + blas.nodes = spanpool.resolve_slice(&sim_state.blas_nodes_pool, s.blas.nodes) + blas.primitives = spanpool.resolve_slice( + &sim_state.blas_primitives_pool, + s.blas.primitives, + ) + blas.nodes_used = i32(len(blas.nodes)) vertices = spanpool.resolve_slice(&sim_state.geometry_vertices_pool, s.geometry.vertices) indices = spanpool.resolve_slice(&sim_state.geometry_indices_pool, s.geometry.indices) case Level_Geom_Source_Asset: - loaded_bvh, reloaded := assets.get_bvh( - sim_state.scene.assetman, - strings.unsafe_string_to_cstring(name.to_string(s.assetpath)), - ) - if reloaded { - level_geom.aabb = bvh_aabb_to_phys_aabb(loaded_bvh.aabb) - level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q) + loaded_bvh, ok := sim_cache.level_geom_asset_bvh[handle] + + if !ok { + reloaded: bool + loaded_bvh, reloaded = assets.get_bvh(sim_state.scene.assetman, s.assetpath) + if reloaded { + level_geom.aabb = bvh_aabb_to_phys_aabb(loaded_bvh.aabb) + level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q) + } + // sim_cache.level_geom_asset_bvh[handle] = loaded_bvh } + + blas = loaded_bvh.bvh vertices = loaded_bvh.vertices indices = loaded_bvh.indices } @@ -976,28 +989,6 @@ get_level_geom_data :: proc( return } -get_level_geom_blas :: proc(sim_state: ^Sim_State, handle: Level_Geom_Handle) -> (bvh: bvh.BVH) { - level_geom := get_level_geom(sim_state, handle) - switch s in level_geom.source { - case Level_Geom_Source_Local: - bvh.nodes = spanpool.resolve_slice(&sim_state.blas_nodes_pool, s.blas.nodes) - bvh.primitives = spanpool.resolve_slice(&sim_state.blas_primitives_pool, s.blas.primitives) - bvh.nodes_used = i32(len(bvh.nodes)) - case Level_Geom_Source_Asset: - loaded_bvh, reloaded := assets.get_bvh( - sim_state.scene.assetman, - strings.unsafe_string_to_cstring(name.to_string(s.assetpath)), - ) - if reloaded { - level_geom.aabb = bvh_aabb_to_phys_aabb(loaded_bvh.aabb) - level_geom.aabb = aabb_transform(level_geom.aabb, level_geom.x, level_geom.q) - } - - bvh = loaded_bvh.bvh - } - return -} - update_level_geom_from_config :: proc( sim_state: ^Sim_State, level_geom: Level_Geom_Ptr, @@ -1063,13 +1054,10 @@ add_level_geom :: proc(sim_state: ^Sim_State, config: Level_Geom_Config) -> Leve level_geom.source = source case Level_Geometry_Asset: level_geom.source = Level_Geom_Source_Asset { - assetpath = name.from_string(string(s)), + assetpath = name.Name(s), } - bvh, _ := assets.get_bvh( - sim_state.scene.assetman, - strings.unsafe_string_to_cstring(string(s)), - ) + bvh, _ := assets.get_bvh(sim_state.scene.assetman, name.Name(s)) level_geom.aabb = AABB { center = (bvh.aabb.max + bvh.aabb.min) * 0.5, extent = (bvh.aabb.max - bvh.aabb.min) * 0.5, @@ -1104,6 +1092,11 @@ remove_level_geom :: proc(sim_state: ^Sim_State, handle: Level_Geom_Handle) { spanpool.free(&sim_state.blas_primitives_pool, s.blas.primitives) case Level_Geom_Source_Asset: } + + level_geom.alive = false + level_geom.next_plus_one = sim_state.first_free_level_geom_plus_one + sim_state.first_free_level_geom_plus_one = i32(handle) + sim_state.num_level_geoms -= 1 } _get_first_free_body :: proc(sim_state: ^Sim_State) -> i32 { diff --git a/game/physics/simulation.odin b/game/physics/simulation.odin index cd8e03a..924a8f2 100644 --- a/game/physics/simulation.odin +++ b/game/physics/simulation.odin @@ -11,6 +11,7 @@ import "core:math" import lg "core:math/linalg" import "core:math/rand" import "core:slice" +import "game:assets" import "game:debug" import he "game:halfedge" import "libs:tracy" @@ -174,8 +175,10 @@ dynamic_tlas_destroy :: proc(dyn_tlas: ^Dynamic_TLAS) { } } + raycasts_level :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, tlas: ^Static_TLAS, origin, dir: Vec3, distance := max(f32), @@ -201,32 +204,31 @@ raycasts_level :: proc( int(tlas.bvh_tree.primitives[leaf_node.child_or_prim_start + j]), ) level_geom := get_level_geom(sim_state, level_geom_handle) - blas := get_level_geom_blas(sim_state, level_geom_handle) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + blas, vertices, indices := get_level_geom_data(sim_state, sim_cache, level_geom_handle) // TODO: transform ray into blas space and back - blas_it := bvh.iterator_intersect_leaf_ray(&blas, ray, distance) + inv_q := lg.quaternion_inverse(level_geom.q) + local_ray := ray + local_ray.origin = lg.quaternion_mul_vector3(inv_q, ray.origin - level_geom.x) + local_ray.dir = lg.quaternion_mul_vector3(inv_q, ray.dir) + local_ray.dir_inv = 1.0 / local_ray.dir + + blas_it := bvh.iterator_intersect_leaf_ray(&blas, local_ray, distance) for blas_leaf_node in bvh.iterator_intersect_leaf_next(&blas_it) { for k in 0 ..< blas_leaf_node.prim_len { tri_idx := int(blas.primitives[blas_leaf_node.child_or_prim_start + k]) - tri := get_transformed_triangle( - vertices, - indices, - tri_idx, - level_geom.x, - level_geom.q, - ) + tri := get_triangle(vertices, indices, tri_idx) hit_t, tmp_normal, _, ok := collision.intersect_ray_triangle( - {origin, origin + dir}, + {local_ray.origin, local_ray.origin + local_ray.dir}, tri, ) if ok && (!hit || hit_t < t) { t = hit_t - normal = tmp_normal + normal = lg.quaternion_mul_vector3(level_geom.q, tmp_normal) hit = true } } @@ -294,6 +296,7 @@ raycast_bodies :: proc( raycast :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, static_tlas: ^Static_TLAS, dyn_tlas: ^Dynamic_TLAS, origin, dir: Vec3, @@ -305,7 +308,7 @@ raycast :: proc( ) { t = distance - t1, normal1, hit1 := raycasts_level(sim_state, static_tlas, origin, dir, t) + t1, normal1, hit1 := raycasts_level(sim_state, sim_cache, static_tlas, origin, dir, t) t2, normal2, hit2 := raycast_bodies(sim_state, dyn_tlas, origin, dir, t) hit = hit1 || hit2 @@ -329,6 +332,14 @@ raycast :: proc( return } +// Cache used during simulation to avoid complex computations +Sim_Cache :: struct { + // Looking up bvh can be expensive because assetman touches the filesystem each time. We assume that during simulation it cannot change + // so it's safe to cache + level_geom_asset_bvh: map[Level_Geom_Handle]assets.Loaded_BVH, +} + + get_triangle :: proc(vertices: []Vec3, indices: []u16, tri_idx: int) -> (tri: [3]Vec3) { i1, i2, i3 := indices[tri_idx * 3 + 0], indices[tri_idx * 3 + 1], indices[tri_idx * 3 + 2] tri[0], tri[1], tri[2] = vertices[i1], vertices[i2], vertices[i3] @@ -361,6 +372,7 @@ get_triangle_aabb :: proc(tri: [3]Vec3) -> (aabb: bvh.AABB) { remove_invalid_contacts :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, static_tlas: Static_TLAS, dyn_tlas: Dynamic_TLAS, ) { @@ -394,7 +406,11 @@ remove_invalid_contacts :: proc( if !should_remove { tri_idx := int(contact.local_tri_idx) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + _, vertices, indices := get_level_geom_data( + sim_state, + sim_cache, + level_geom_handle, + ) should_remove |= tri_idx * 3 >= len(indices) if !should_remove { @@ -453,6 +469,7 @@ remove_invalid_contacts :: proc( // TODO: free intermediate temp allocs find_new_contacts :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, static_tlas: ^Static_TLAS, dyn_tlas: ^Dynamic_TLAS, ) { @@ -559,10 +576,16 @@ find_new_contacts :: proc( ) level_geom := get_level_geom(sim_state, level_geom_handle) if level_geom.alive { - blas := get_level_geom_blas(sim_state, level_geom_handle) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + blas, vertices, indices := get_level_geom_data( + sim_state, + sim_cache, + level_geom_handle, + ) - blas_it := bvh.iterator_intersect_leaf_aabb(&blas, body_aabb) + blas_it := bvh.iterator_intersect_leaf_aabb( + &blas, + aabb_inv_transform(body_aabb, level_geom.x, level_geom.q), + ) for blas_leaf_node in bvh.iterator_intersect_leaf_next(&blas_it) { for k in 0 ..< blas_leaf_node.prim_len { tri_idx := int( @@ -653,9 +676,16 @@ simulate :: proc( prune_immediate(scene) copy_sim_state(get_next_sim_state(scene), get_sim_state(scene)) - sim_state := get_next_sim_state(scene) + // runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + + sim_cache: Sim_Cache + sim_cache.level_geom_asset_bvh = make_map( + map[Level_Geom_Handle]assets.Loaded_BVH, + context.temp_allocator, + ) + num_steps := 0 switch step_mode { case .Accumulated_Time: @@ -666,11 +696,11 @@ simulate :: proc( state.accumulated_time -= config.timestep if num_steps < MAX_STEPS { - simulate_step(scene, sim_state, config) + simulate_step(scene, sim_state, &sim_cache, config) } } case .Single: - simulate_step(scene, get_next_sim_state(scene), config) + simulate_step(scene, get_next_sim_state(scene), &sim_cache, config) num_steps += 1 } @@ -718,7 +748,7 @@ Contact :: struct { applied_normal_correction: [4]f32, } -update_contacts :: proc(sim_state: ^Sim_State, static_tlas: ^Static_TLAS) { +update_contacts :: proc(sim_state: ^Sim_State, sim_cache: ^Sim_Cache, static_tlas: ^Static_TLAS) { tracy.Zone() temp := runtime.default_temp_allocator_temp_begin() @@ -824,7 +854,7 @@ update_contacts :: proc(sim_state: ^Sim_State, static_tlas: ^Static_TLAS) { case .Body_vs_Level: level_geom_handle := Level_Geom_Handle(contact.b) level_geom := get_level_geom(sim_state, level_geom_handle) - vertices, indices := get_level_geom_data(sim_state, level_geom_handle) + _, vertices, indices := get_level_geom_data(sim_state, sim_cache, level_geom_handle) tri := get_transformed_triangle( vertices, indices, @@ -1232,6 +1262,7 @@ calculate_ground_vel :: proc( pgs_solve_suspension :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, static_tlas: ^Static_TLAS, dyn_tlas: ^Dynamic_TLAS, config: Solver_Config, @@ -1249,6 +1280,7 @@ pgs_solve_suspension :: proc( dir := body_local_to_world_vec(body, v.rel_dir) v.hit_t, v.hit_normal, v.hit = raycast( sim_state, + sim_cache, static_tlas, dyn_tlas, wheel_world_pos, @@ -1438,6 +1470,7 @@ pgs_solve_suspension :: proc( pgs_substep :: proc( sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, static_tlas: ^Static_TLAS, dyn_tlas: ^Dynamic_TLAS, config: Solver_Config, @@ -1559,7 +1592,7 @@ pgs_substep :: proc( apply_bias := true pgs_solve_contacts(sim_state, config, dt, inv_dt, apply_bias) pgs_solve_engines(sim_state, config, dt, inv_dt) - pgs_solve_suspension(sim_state, static_tlas, dyn_tlas, config, dt, inv_dt) + pgs_solve_suspension(sim_state, sim_cache, static_tlas, dyn_tlas, config, dt, inv_dt) for i in 0 ..< len(sim_state.bodies_slice) { body := &sim_state.bodies_slice[i] @@ -1600,7 +1633,12 @@ pgs_substep :: proc( // pgs_solve_suspension(sim_state, config, dt, inv_dt, apply_bias) } -simulate_step :: proc(scene: ^Scene, sim_state: ^Sim_State, config: Solver_Config) { +simulate_step :: proc( + scene: ^Scene, + sim_state: ^Sim_State, + sim_cache: ^Sim_Cache, + config: Solver_Config, +) { tracy.Zone() substeps := config.substreps_minus_one + 1 @@ -1614,9 +1652,9 @@ simulate_step :: proc(scene: ^Scene, sim_state: ^Sim_State, config: Solver_Confi build_static_tlas(sim_state, &sim_state.static_tlas) build_dynamic_tlas(sim_state, config, &sim_state.dynamic_tlas) - remove_invalid_contacts(sim_state, sim_state.static_tlas, sim_state.dynamic_tlas) - find_new_contacts(sim_state, &sim_state.static_tlas, &sim_state.dynamic_tlas) - update_contacts(sim_state, &sim_state.static_tlas) + remove_invalid_contacts(sim_state, sim_cache, sim_state.static_tlas, sim_state.dynamic_tlas) + find_new_contacts(sim_state, sim_cache, &sim_state.static_tlas, &sim_state.dynamic_tlas) + update_contacts(sim_state, sim_cache, &sim_state.static_tlas) Solver :: enum { XPBD, @@ -1634,6 +1672,7 @@ simulate_step :: proc(scene: ^Scene, sim_state: ^Sim_State, config: Solver_Confi for _ in 0 ..< substeps { pgs_substep( sim_state, + sim_cache, &sim_state.static_tlas, &sim_state.dynamic_tlas, config, diff --git a/libs/raylib/easings.odin b/libs/raylib/easings.odin index ad9a47a..1751405 100644 --- a/libs/raylib/easings.odin +++ b/libs/raylib/easings.odin @@ -220,4 +220,4 @@ EaseElasticInOut :: proc(t, b, c, d: f32) -> f32 { postFix := a*math.pow(2.0, -10.0*t) return (postFix*math.sin((t*d-s)*(2.0*PI)/p)*0.5 + c + b) -} \ No newline at end of file +} diff --git a/libs/raylib/raygui.odin b/libs/raylib/raygui.odin index 40fb025..559437a 100644 --- a/libs/raylib/raygui.odin +++ b/libs/raylib/raygui.odin @@ -2,565 +2,565 @@ package raylib import "core:c" -_ :: c - -RAYGUI_ENABLED :: #config(RAYGUI_ENABLED, false) RAYGUI_SHARED :: #config(RAYGUI_SHARED, false) +RAYGUI_WASM_LIB :: #config(RAYGUI_WASM_LIB, "wasm/libraygui.a") -when RAYGUI_ENABLED { - when ODIN_OS == .Windows { - foreign import lib { - "windows/rayguidll.lib" when RAYGUI_SHARED else "windows/raygui.lib", - } - } else when ODIN_OS == .Linux { - foreign import lib { - "linux/libraygui.so" when RAYGUI_SHARED else "linux/libraygui.a", - } - } else when ODIN_OS == .Darwin { - when ODIN_ARCH == .arm64 { - foreign import lib { - "macos-arm64/libraygui.dylib" when RAYGUI_SHARED else "macos-arm64/libraygui.a", - } - } else { - foreign import lib { - "macos/libraygui.dylib" when RAYGUI_SHARED else "macos/libraygui.a", - } - } - } else { - foreign import lib "system:raygui" - } - - RAYGUI_VERSION :: "4.0" - - // Gui control state - GuiState :: enum c.int { - STATE_NORMAL = 0, - STATE_FOCUSED, - STATE_PRESSED, - STATE_DISABLED, - } - - // Gui control text alignment - GuiTextAlignment :: enum c.int { - TEXT_ALIGN_LEFT = 0, - TEXT_ALIGN_CENTER, - TEXT_ALIGN_RIGHT, - } - - GuiTextAlignmentVertical :: enum c.int { - TEXT_ALIGN_TOP = 0, - TEXT_ALIGN_MIDDLE, - TEXT_ALIGN_BOTTOM, - } - - GuiTextWrapMode :: enum c.int { - TEXT_WRAP_NONE = 0, - TEXT_WRAP_CHAR, - TEXT_WRAP_WORD, - } - - // Gui controls - GuiControl :: enum c.int { - // Default -> populates to all controls when set - DEFAULT = 0, - // Basic controls - LABEL, // Used also for: LABELBUTTON - BUTTON, - TOGGLE, // Used also for: TOGGLEGROUP - SLIDER, // Used also for: SLIDERBAR - PROGRESSBAR, - CHECKBOX, - COMBOBOX, - DROPDOWNBOX, - TEXTBOX, // Used also for: TEXTBOXMULTI - VALUEBOX, - SPINNER, // Uses: BUTTON, VALUEBOX - LISTVIEW, - COLORPICKER, - SCROLLBAR, - STATUSBAR, - } - - // Gui base properties for every control - // NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties) - GuiControlProperty :: enum c.int { - BORDER_COLOR_NORMAL = 0, - BASE_COLOR_NORMAL, - TEXT_COLOR_NORMAL, - BORDER_COLOR_FOCUSED, - BASE_COLOR_FOCUSED, - TEXT_COLOR_FOCUSED, - BORDER_COLOR_PRESSED, - BASE_COLOR_PRESSED, - TEXT_COLOR_PRESSED, - BORDER_COLOR_DISABLED, - BASE_COLOR_DISABLED, - TEXT_COLOR_DISABLED, - BORDER_WIDTH, - TEXT_PADDING, - TEXT_ALIGNMENT, - RESERVED, - } - - // Gui extended properties depend on control - // NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) - //---------------------------------------------------------------------------------- - - // DEFAULT extended properties - // NOTE: Those properties are common to all controls or global - GuiDefaultProperty :: enum c.int { - TEXT_SIZE = 16, // Text size (glyphs max height) - TEXT_SPACING, // Text spacing between glyphs - LINE_COLOR, // Line control color - BACKGROUND_COLOR, // Background color - TEXT_LINE_SPACING, // Text spacing between lines - TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) - TEXT_WRAP_MODE, // Text wrap-mode inside text bounds - } - - // Label - //GuiLabelProperty :: enum c.int { } - - // Button/Spinner - //GuiButtonProperty :: enum c.int { } - - // Toggle/ToggleGroup - GuiToggleProperty :: enum c.int { - GROUP_PADDING = 16, // ToggleGroup separation between toggles - } - - // Slider/SliderBar - GuiSliderProperty :: enum c.int { - SLIDER_WIDTH = 16, // Slider size of internal bar - SLIDER_PADDING, // Slider/SliderBar internal bar padding - } - - // ProgressBar - GuiProgressBarProperty :: enum c.int { - PROGRESS_PADDING = 16, // ProgressBar internal padding - } - - // ScrollBar - GuiScrollBarProperty :: enum c.int { - ARROWS_SIZE = 16, - ARROWS_VISIBLE, - SCROLL_SLIDER_PADDING, // (SLIDERBAR, SLIDER_PADDING) - SCROLL_SLIDER_SIZE, - SCROLL_PADDING, - SCROLL_SPEED, - } - - // CheckBox - GuiCheckBoxProperty :: enum c.int { - CHECK_PADDING = 16, // CheckBox internal check padding - } - - // ComboBox - GuiComboBoxProperty :: enum c.int { - COMBO_BUTTON_WIDTH = 16, // ComboBox right button width - COMBO_BUTTON_SPACING, // ComboBox button separation - } - - // DropdownBox - GuiDropdownBoxProperty :: enum c.int { - ARROW_PADDING = 16, // DropdownBox arrow separation from border and items - DROPDOWN_ITEMS_SPACING, // DropdownBox items separation - } - - // TextBox/TextBoxMulti/ValueBox/Spinner - GuiTextBoxProperty :: enum c.int { - TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable - } - - // Spinner - GuiSpinnerProperty :: enum c.int { - SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width - SPIN_BUTTON_SPACING, // Spinner buttons separation - } - - // ListView - GuiListViewProperty :: enum c.int { - LIST_ITEMS_HEIGHT = 16, // ListView items height - LIST_ITEMS_SPACING, // ListView items separation - SCROLLBAR_WIDTH, // ListView scrollbar size (usually width) - SCROLLBAR_SIDE, // ListView scrollbar side (0-left, 1-right) - } - - // ColorPicker - GuiColorPickerProperty :: enum c.int { - COLOR_SELECTOR_SIZE = 16, - HUEBAR_WIDTH, // ColorPicker right hue bar width - HUEBAR_PADDING, // ColorPicker right hue bar separation from panel - HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height - HUEBAR_SELECTOR_OVERFLOW, // ColorPicker right hue bar selector overflow - } - - SCROLLBAR_LEFT_SIDE :: 0 - SCROLLBAR_RIGHT_SIDE :: 1 - - //---------------------------------------------------------------------------------- - // Global Variables Definition - //---------------------------------------------------------------------------------- - // ... - - //---------------------------------------------------------------------------------- - // Module Functions Declaration - //---------------------------------------------------------------------------------- - - @(default_calling_convention="c") - foreign lib { - // WASM does not have foreign variable declarations. - when ODIN_ARCH != .wasm32 && ODIN_ARCH != .wasm64p32 { - @(link_name="raylib_version") version: cstring - } - // Global gui state control functions - - GuiEnable :: proc() --- // Enable gui controls (global state) - GuiLock :: proc() --- // Lock gui controls (global state) - GuiDisable :: proc() --- // Disable gui controls (global state) - GuiUnlock :: proc() --- // Unlock gui controls (global state) - GuiIsLocked :: proc() -> bool --- // Check if gui is locked (global state) - GuiSetAlpha :: proc(alpha: f32) --- // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f - GuiSetState :: proc(state: c.int) --- // Set gui state (global state) - GuiGetState :: proc() -> c.int --- // Get gui state (global state) - - // Font set/get functions - - GuiSetFont :: proc(font: Font) --- // Set gui custom font (global state) - GuiGetFont :: proc() -> Font --- // Get gui custom font (global state) - - // Style set/get functions - - GuiSetStyle :: proc(control: GuiControl, property: c.int, value: c.int) --- // Set one style property - GuiGetStyle :: proc(control: GuiControl, property: c.int) -> c.int --- // Get one style property - - // Styles loading functions - - GuiLoadStyle :: proc(fileName: cstring) --- // Load style file over global style variable (.rgs) - GuiLoadStyleDefault :: proc() --- // Load style default over global style - - // Tooltips management functions - - GuiEnableTooltip :: proc() --- // Enable gui tooltips (global state) - GuiDisableTooltip :: proc() --- // Disable gui tooltips (global state) - GuiSetTooltip :: proc(tooltip: cstring) --- // Set tooltip string - - // Icons functionality - - GuiIconText :: proc(iconId: GuiIconName, text: cstring) -> cstring --- // Get text with icon id prepended (if supported) - GuiSetIconScale :: proc(scale: c.int) --- // Set default icon drawing size - GuiGetIcons :: proc() -> [^]u32 --- // Get raygui icons data pointer - GuiLoadIcons :: proc(fileName: cstring, loadIconsName: bool) -> [^]cstring --- // Load raygui icons file (.rgi) into internal icons data - GuiDrawIcon :: proc(iconId: GuiIconName, posX, posY: c.int, pixelSize: c.int, color: Color) --- // Draw icon using pixel size at specified position - - - // Controls - //---------------------------------------------------------------------------------------------------------- - // Container/separator controls, useful for controls organization - - GuiWindowBox :: proc(bounds: Rectangle, title: cstring) -> c.int --- // Window Box control, shows a window that can be closed - GuiGroupBox :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Group Box control with text name - GuiLine :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Line separator control, could contain text - GuiPanel :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Panel control, useful to group controls - GuiTabBar :: proc(bounds: Rectangle, text: [^]cstring, count: c.int, active: ^c.int) -> c.int --- // Tab Bar control, returns TAB to be closed or -1 - GuiScrollPanel :: proc(bounds: Rectangle, text: cstring, content: Rectangle, scroll: ^Vector2, view: ^Rectangle) -> c.int --- // Scroll Panel control - - // Basic controls set - - GuiLabel :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Label control, shows text - GuiButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Button control, returns true when clicked - GuiLabelButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Label button control, show true when clicked - GuiToggle :: proc(bounds: Rectangle, text: cstring, active: ^bool) -> c.int --- // Toggle Button control, returns true when active - GuiToggleGroup :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Toggle Group control, returns active toggle index - GuiToggleSlider :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- - GuiCheckBox :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> bool --- // Check Box control, returns true when active - GuiComboBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Combo Box control, returns selected item index - - GuiDropdownBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> bool --- // Dropdown Box control, returns selected item - GuiSpinner :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Spinner control, returns selected value - GuiValueBox :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Value Box control, updates input text with numbers - GuiTextBox :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> bool --- // Text Box control, updates input text - - GuiSlider :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider control, returns selected value - GuiSliderBar :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider Bar control, returns selected value - GuiProgressBar :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Progress Bar control, shows current progress value - GuiStatusBar :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Status Bar control, shows info text - GuiDummyRec :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Dummy control for placeholders - GuiGrid :: proc(bounds: Rectangle, text: cstring, spacing: f32, subdivs: c.int, mouseCell: ^Vector2) -> c.int --- // Grid control, returns mouse cell position - - // Advance controls set - GuiListView :: proc(bounds: Rectangle, text: cstring, scrollIndex: ^c.int, active: ^c.int) -> c.int --- // List View control, returns selected list item index - GuiListViewEx :: proc(bounds: Rectangle, text:[^]cstring, count: c.int, scrollIndex: ^c.int, active: ^c.int, focus: ^c.int) -> c.int --- // List View with extended parameters - GuiMessageBox :: proc(bounds: Rectangle, title: cstring, message: cstring, buttons: cstring) -> c.int --- // Message Box control, displays a message - GuiTextInputBox :: proc(bounds: Rectangle, title: cstring, message: cstring, buttons: cstring, text: cstring, textMaxSize: c.int, secretViewActive: ^bool) -> c.int --- // Text Input Box control, ask for text, supports secret - GuiColorPicker :: proc(bounds: Rectangle, text: cstring, color: ^Color) -> c.int --- // Color Picker control (multiple color controls) - GuiColorPanel :: proc(bounds: Rectangle, text: cstring, color: ^Color) -> c.int --- // Color Panel control - GuiColorBarAlpha :: proc(bounds: Rectangle, text: cstring, alpha: ^f32) -> c.int --- // Color Bar Alpha control - GuiColorBarHue :: proc(bounds: Rectangle, text: cstring, value: ^f32) -> c.int --- // Color Bar Hue control - GuiColorPickerHSV :: proc(bounds: Rectangle, text: cstring, colorHsv: ^Vector3) -> c.int --- // Color Picker control that avoids conversion to RGB on each call (multiple color controls) - GuiColorPanelHSV :: proc(bounds: Rectangle, text: cstring, colorHsv: ^Vector3) -> c.int --- // Color Panel control that returns HSV color value, used by GuiColorPickerHSV() - //---------------------------------------------------------------------------------------------------------- - } - - //---------------------------------------------------------------------------------- - // Icons enumeration - //---------------------------------------------------------------------------------- - GuiIconName :: enum c.int { - ICON_NONE = 0, - ICON_FOLDER_FILE_OPEN = 1, - ICON_FILE_SAVE_CLASSIC = 2, - ICON_FOLDER_OPEN = 3, - ICON_FOLDER_SAVE = 4, - ICON_FILE_OPEN = 5, - ICON_FILE_SAVE = 6, - ICON_FILE_EXPORT = 7, - ICON_FILE_ADD = 8, - ICON_FILE_DELETE = 9, - ICON_FILETYPE_TEXT = 10, - ICON_FILETYPE_AUDIO = 11, - ICON_FILETYPE_IMAGE = 12, - ICON_FILETYPE_PLAY = 13, - ICON_FILETYPE_VIDEO = 14, - ICON_FILETYPE_INFO = 15, - ICON_FILE_COPY = 16, - ICON_FILE_CUT = 17, - ICON_FILE_PASTE = 18, - ICON_CURSOR_HAND = 19, - ICON_CURSOR_POINTER = 20, - ICON_CURSOR_CLASSIC = 21, - ICON_PENCIL = 22, - ICON_PENCIL_BIG = 23, - ICON_BRUSH_CLASSIC = 24, - ICON_BRUSH_PAINTER = 25, - ICON_WATER_DROP = 26, - ICON_COLOR_PICKER = 27, - ICON_RUBBER = 28, - ICON_COLOR_BUCKET = 29, - ICON_TEXT_T = 30, - ICON_TEXT_A = 31, - ICON_SCALE = 32, - ICON_RESIZE = 33, - ICON_FILTER_POINT = 34, - ICON_FILTER_BILINEAR = 35, - ICON_CROP = 36, - ICON_CROP_ALPHA = 37, - ICON_SQUARE_TOGGLE = 38, - ICON_SYMMETRY = 39, - ICON_SYMMETRY_HORIZONTAL = 40, - ICON_SYMMETRY_VERTICAL = 41, - ICON_LENS = 42, - ICON_LENS_BIG = 43, - ICON_EYE_ON = 44, - ICON_EYE_OFF = 45, - ICON_FILTER_TOP = 46, - ICON_FILTER = 47, - ICON_TARGET_POINT = 48, - ICON_TARGET_SMALL = 49, - ICON_TARGET_BIG = 50, - ICON_TARGET_MOVE = 51, - ICON_CURSOR_MOVE = 52, - ICON_CURSOR_SCALE = 53, - ICON_CURSOR_SCALE_RIGHT = 54, - ICON_CURSOR_SCALE_LEFT = 55, - ICON_UNDO = 56, - ICON_REDO = 57, - ICON_REREDO = 58, - ICON_MUTATE = 59, - ICON_ROTATE = 60, - ICON_REPEAT = 61, - ICON_SHUFFLE = 62, - ICON_EMPTYBOX = 63, - ICON_TARGET = 64, - ICON_TARGET_SMALL_FILL = 65, - ICON_TARGET_BIG_FILL = 66, - ICON_TARGET_MOVE_FILL = 67, - ICON_CURSOR_MOVE_FILL = 68, - ICON_CURSOR_SCALE_FILL = 69, - ICON_CURSOR_SCALE_RIGHT_FILL = 70, - ICON_CURSOR_SCALE_LEFT_FILL = 71, - ICON_UNDO_FILL = 72, - ICON_REDO_FILL = 73, - ICON_REREDO_FILL = 74, - ICON_MUTATE_FILL = 75, - ICON_ROTATE_FILL = 76, - ICON_REPEAT_FILL = 77, - ICON_SHUFFLE_FILL = 78, - ICON_EMPTYBOX_SMALL = 79, - ICON_BOX = 80, - ICON_BOX_TOP = 81, - ICON_BOX_TOP_RIGHT = 82, - ICON_BOX_RIGHT = 83, - ICON_BOX_BOTTOM_RIGHT = 84, - ICON_BOX_BOTTOM = 85, - ICON_BOX_BOTTOM_LEFT = 86, - ICON_BOX_LEFT = 87, - ICON_BOX_TOP_LEFT = 88, - ICON_BOX_CENTER = 89, - ICON_BOX_CIRCLE_MASK = 90, - ICON_POT = 91, - ICON_ALPHA_MULTIPLY = 92, - ICON_ALPHA_CLEAR = 93, - ICON_DITHERING = 94, - ICON_MIPMAPS = 95, - ICON_BOX_GRID = 96, - ICON_GRID = 97, - ICON_BOX_CORNERS_SMALL = 98, - ICON_BOX_CORNERS_BIG = 99, - ICON_FOUR_BOXES = 100, - ICON_GRID_FILL = 101, - ICON_BOX_MULTISIZE = 102, - ICON_ZOOM_SMALL = 103, - ICON_ZOOM_MEDIUM = 104, - ICON_ZOOM_BIG = 105, - ICON_ZOOM_ALL = 106, - ICON_ZOOM_CENTER = 107, - ICON_BOX_DOTS_SMALL = 108, - ICON_BOX_DOTS_BIG = 109, - ICON_BOX_CONCENTRIC = 110, - ICON_BOX_GRID_BIG = 111, - ICON_OK_TICK = 112, - ICON_CROSS = 113, - ICON_ARROW_LEFT = 114, - ICON_ARROW_RIGHT = 115, - ICON_ARROW_DOWN = 116, - ICON_ARROW_UP = 117, - ICON_ARROW_LEFT_FILL = 118, - ICON_ARROW_RIGHT_FILL = 119, - ICON_ARROW_DOWN_FILL = 120, - ICON_ARROW_UP_FILL = 121, - ICON_AUDIO = 122, - ICON_FX = 123, - ICON_WAVE = 124, - ICON_WAVE_SINUS = 125, - ICON_WAVE_SQUARE = 126, - ICON_WAVE_TRIANGULAR = 127, - ICON_CROSS_SMALL = 128, - ICON_PLAYER_PREVIOUS = 129, - ICON_PLAYER_PLAY_BACK = 130, - ICON_PLAYER_PLAY = 131, - ICON_PLAYER_PAUSE = 132, - ICON_PLAYER_STOP = 133, - ICON_PLAYER_NEXT = 134, - ICON_PLAYER_RECORD = 135, - ICON_MAGNET = 136, - ICON_LOCK_CLOSE = 137, - ICON_LOCK_OPEN = 138, - ICON_CLOCK = 139, - ICON_TOOLS = 140, - ICON_GEAR = 141, - ICON_GEAR_BIG = 142, - ICON_BIN = 143, - ICON_HAND_POINTER = 144, - ICON_LASER = 145, - ICON_COIN = 146, - ICON_EXPLOSION = 147, - ICON_1UP = 148, - ICON_PLAYER = 149, - ICON_PLAYER_JUMP = 150, - ICON_KEY = 151, - ICON_DEMON = 152, - ICON_TEXT_POPUP = 153, - ICON_GEAR_EX = 154, - ICON_CRACK = 155, - ICON_CRACK_POINTS = 156, - ICON_STAR = 157, - ICON_DOOR = 158, - ICON_EXIT = 159, - ICON_MODE_2D = 160, - ICON_MODE_3D = 161, - ICON_CUBE = 162, - ICON_CUBE_FACE_TOP = 163, - ICON_CUBE_FACE_LEFT = 164, - ICON_CUBE_FACE_FRONT = 165, - ICON_CUBE_FACE_BOTTOM = 166, - ICON_CUBE_FACE_RIGHT = 167, - ICON_CUBE_FACE_BACK = 168, - ICON_CAMERA = 169, - ICON_SPECIAL = 170, - ICON_LINK_NET = 171, - ICON_LINK_BOXES = 172, - ICON_LINK_MULTI = 173, - ICON_LINK = 174, - ICON_LINK_BROKE = 175, - ICON_TEXT_NOTES = 176, - ICON_NOTEBOOK = 177, - ICON_SUITCASE = 178, - ICON_SUITCASE_ZIP = 179, - ICON_MAILBOX = 180, - ICON_MONITOR = 181, - ICON_PRINTER = 182, - ICON_PHOTO_CAMERA = 183, - ICON_PHOTO_CAMERA_FLASH = 184, - ICON_HOUSE = 185, - ICON_HEART = 186, - ICON_CORNER = 187, - ICON_VERTICAL_BARS = 188, - ICON_VERTICAL_BARS_FILL = 189, - ICON_LIFE_BARS = 190, - ICON_INFO = 191, - ICON_CROSSLINE = 192, - ICON_HELP = 193, - ICON_FILETYPE_ALPHA = 194, - ICON_FILETYPE_HOME = 195, - ICON_LAYERS_VISIBLE = 196, - ICON_LAYERS = 197, - ICON_WINDOW = 198, - ICON_HIDPI = 199, - ICON_FILETYPE_BINARY = 200, - ICON_HEX = 201, - ICON_SHIELD = 202, - ICON_FILE_NEW = 203, - ICON_FOLDER_ADD = 204, - ICON_ALARM = 205, - ICON_CPU = 206, - ICON_ROM = 207, - ICON_STEP_OVER = 208, - ICON_STEP_INTO = 209, - ICON_STEP_OUT = 210, - ICON_RESTART = 211, - ICON_BREAKPOINT_ON = 212, - ICON_BREAKPOINT_OFF = 213, - ICON_BURGER_MENU = 214, - ICON_CASE_SENSITIVE = 215, - ICON_REG_EXP = 216, - ICON_FOLDER = 217, - ICON_FILE = 218, - ICON_SAND_TIMER = 219, - ICON_220 = 220, - ICON_221 = 221, - ICON_222 = 222, - ICON_223 = 223, - ICON_224 = 224, - ICON_225 = 225, - ICON_226 = 226, - ICON_227 = 227, - ICON_228 = 228, - ICON_229 = 229, - ICON_230 = 230, - ICON_231 = 231, - ICON_232 = 232, - ICON_233 = 233, - ICON_234 = 234, - ICON_235 = 235, - ICON_236 = 236, - ICON_237 = 237, - ICON_238 = 238, - ICON_239 = 239, - ICON_240 = 240, - ICON_241 = 241, - ICON_242 = 242, - ICON_243 = 243, - ICON_244 = 244, - ICON_245 = 245, - ICON_246 = 246, - ICON_247 = 247, - ICON_248 = 248, - ICON_249 = 249, - ICON_250 = 250, - ICON_251 = 251, - ICON_252 = 252, - ICON_253 = 253, - ICON_254 = 254, - ICON_255 = 255, - } +when ODIN_OS == .Windows { + foreign import lib { + "windows/rayguidll.lib" when RAYGUI_SHARED else "windows/raygui.lib", + } +} else when ODIN_OS == .Linux { + foreign import lib { + "linux/libraygui.so" when RAYGUI_SHARED else "linux/libraygui.a", + } +} else when ODIN_OS == .Darwin { + when ODIN_ARCH == .arm64 { + foreign import lib { + "macos-arm64/libraygui.dylib" when RAYGUI_SHARED else "macos-arm64/libraygui.a", + } + } else { + foreign import lib { + "macos/libraygui.dylib" when RAYGUI_SHARED else "macos/libraygui.a", + } + } +} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 { + foreign import lib { + RAYGUI_WASM_LIB, + } +} else { + foreign import lib "system:raygui" +} + +RAYGUI_VERSION :: "4.0" + +// Gui control state +GuiState :: enum c.int { + STATE_NORMAL = 0, + STATE_FOCUSED, + STATE_PRESSED, + STATE_DISABLED, +} + +// Gui control text alignment +GuiTextAlignment :: enum c.int { + TEXT_ALIGN_LEFT = 0, + TEXT_ALIGN_CENTER, + TEXT_ALIGN_RIGHT, +} + +GuiTextAlignmentVertical :: enum c.int { + TEXT_ALIGN_TOP = 0, + TEXT_ALIGN_MIDDLE, + TEXT_ALIGN_BOTTOM, +} + +GuiTextWrapMode :: enum c.int { + TEXT_WRAP_NONE = 0, + TEXT_WRAP_CHAR, + TEXT_WRAP_WORD, +} + +// Gui controls +GuiControl :: enum c.int { + // Default -> populates to all controls when set + DEFAULT = 0, + // Basic controls + LABEL, // Used also for: LABELBUTTON + BUTTON, + TOGGLE, // Used also for: TOGGLEGROUP + SLIDER, // Used also for: SLIDERBAR + PROGRESSBAR, + CHECKBOX, + COMBOBOX, + DROPDOWNBOX, + TEXTBOX, // Used also for: TEXTBOXMULTI + VALUEBOX, + SPINNER, // Uses: BUTTON, VALUEBOX + LISTVIEW, + COLORPICKER, + SCROLLBAR, + STATUSBAR, +} + +// Gui base properties for every control +// NOTE: RAYGUI_MAX_PROPS_BASE properties (by default 16 properties) +GuiControlProperty :: enum c.int { + BORDER_COLOR_NORMAL = 0, + BASE_COLOR_NORMAL, + TEXT_COLOR_NORMAL, + BORDER_COLOR_FOCUSED, + BASE_COLOR_FOCUSED, + TEXT_COLOR_FOCUSED, + BORDER_COLOR_PRESSED, + BASE_COLOR_PRESSED, + TEXT_COLOR_PRESSED, + BORDER_COLOR_DISABLED, + BASE_COLOR_DISABLED, + TEXT_COLOR_DISABLED, + BORDER_WIDTH, + TEXT_PADDING, + TEXT_ALIGNMENT, + RESERVED, +} + +// Gui extended properties depend on control +// NOTE: RAYGUI_MAX_PROPS_EXTENDED properties (by default, max 8 properties) +//---------------------------------------------------------------------------------- + +// DEFAULT extended properties +// NOTE: Those properties are common to all controls or global +GuiDefaultProperty :: enum c.int { + TEXT_SIZE = 16, // Text size (glyphs max height) + TEXT_SPACING, // Text spacing between glyphs + LINE_COLOR, // Line control color + BACKGROUND_COLOR, // Background color + TEXT_LINE_SPACING, // Text spacing between lines + TEXT_ALIGNMENT_VERTICAL, // Text vertical alignment inside text bounds (after border and padding) + TEXT_WRAP_MODE, // Text wrap-mode inside text bounds +} + +// Label +//GuiLabelProperty :: enum c.int { } + +// Button/Spinner +//GuiButtonProperty :: enum c.int { } + +// Toggle/ToggleGroup +GuiToggleProperty :: enum c.int { + GROUP_PADDING = 16, // ToggleGroup separation between toggles +} + +// Slider/SliderBar +GuiSliderProperty :: enum c.int { + SLIDER_WIDTH = 16, // Slider size of internal bar + SLIDER_PADDING, // Slider/SliderBar internal bar padding +} + +// ProgressBar +GuiProgressBarProperty :: enum c.int { + PROGRESS_PADDING = 16, // ProgressBar internal padding +} + +// ScrollBar +GuiScrollBarProperty :: enum c.int { + ARROWS_SIZE = 16, + ARROWS_VISIBLE, + SCROLL_SLIDER_PADDING, // (SLIDERBAR, SLIDER_PADDING) + SCROLL_SLIDER_SIZE, + SCROLL_PADDING, + SCROLL_SPEED, +} + +// CheckBox +GuiCheckBoxProperty :: enum c.int { + CHECK_PADDING = 16, // CheckBox internal check padding +} + +// ComboBox +GuiComboBoxProperty :: enum c.int { + COMBO_BUTTON_WIDTH = 16, // ComboBox right button width + COMBO_BUTTON_SPACING, // ComboBox button separation +} + +// DropdownBox +GuiDropdownBoxProperty :: enum c.int { + ARROW_PADDING = 16, // DropdownBox arrow separation from border and items + DROPDOWN_ITEMS_SPACING, // DropdownBox items separation +} + +// TextBox/TextBoxMulti/ValueBox/Spinner +GuiTextBoxProperty :: enum c.int { + TEXT_READONLY = 16, // TextBox in read-only mode: 0-text editable, 1-text no-editable +} + +// Spinner +GuiSpinnerProperty :: enum c.int { + SPIN_BUTTON_WIDTH = 16, // Spinner left/right buttons width + SPIN_BUTTON_SPACING, // Spinner buttons separation +} + +// ListView +GuiListViewProperty :: enum c.int { + LIST_ITEMS_HEIGHT = 16, // ListView items height + LIST_ITEMS_SPACING, // ListView items separation + SCROLLBAR_WIDTH, // ListView scrollbar size (usually width) + SCROLLBAR_SIDE, // ListView scrollbar side (0-left, 1-right) +} + +// ColorPicker +GuiColorPickerProperty :: enum c.int { + COLOR_SELECTOR_SIZE = 16, + HUEBAR_WIDTH, // ColorPicker right hue bar width + HUEBAR_PADDING, // ColorPicker right hue bar separation from panel + HUEBAR_SELECTOR_HEIGHT, // ColorPicker right hue bar selector height + HUEBAR_SELECTOR_OVERFLOW, // ColorPicker right hue bar selector overflow +} + +SCROLLBAR_LEFT_SIDE :: 0 +SCROLLBAR_RIGHT_SIDE :: 1 + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +// ... + +//---------------------------------------------------------------------------------- +// Module Functions Declaration +//---------------------------------------------------------------------------------- + +@(default_calling_convention="c") +foreign lib { + // WASM does not have foreign variable declarations. + when ODIN_ARCH != .wasm32 && ODIN_ARCH != .wasm64p32 { + @(link_name="raylib_version") version: cstring + } + // Global gui state control functions + + GuiEnable :: proc() --- // Enable gui controls (global state) + GuiLock :: proc() --- // Lock gui controls (global state) + GuiDisable :: proc() --- // Disable gui controls (global state) + GuiUnlock :: proc() --- // Unlock gui controls (global state) + GuiIsLocked :: proc() -> bool --- // Check if gui is locked (global state) + GuiSetAlpha :: proc(alpha: f32) --- // Set gui controls alpha (global state), alpha goes from 0.0f to 1.0f + GuiSetState :: proc(state: c.int) --- // Set gui state (global state) + GuiGetState :: proc() -> c.int --- // Get gui state (global state) + + // Font set/get functions + + GuiSetFont :: proc(font: Font) --- // Set gui custom font (global state) + GuiGetFont :: proc() -> Font --- // Get gui custom font (global state) + + // Style set/get functions + + GuiSetStyle :: proc(control: GuiControl, property: c.int, value: c.int) --- // Set one style property + GuiGetStyle :: proc(control: GuiControl, property: c.int) -> c.int --- // Get one style property + + // Styles loading functions + + GuiLoadStyle :: proc(fileName: cstring) --- // Load style file over global style variable (.rgs) + GuiLoadStyleDefault :: proc() --- // Load style default over global style + + // Tooltips management functions + + GuiEnableTooltip :: proc() --- // Enable gui tooltips (global state) + GuiDisableTooltip :: proc() --- // Disable gui tooltips (global state) + GuiSetTooltip :: proc(tooltip: cstring) --- // Set tooltip string + + // Icons functionality + + GuiIconText :: proc(iconId: GuiIconName, text: cstring) -> cstring --- // Get text with icon id prepended (if supported) + GuiSetIconScale :: proc(scale: c.int) --- // Set default icon drawing size + GuiGetIcons :: proc() -> [^]u32 --- // Get raygui icons data pointer + GuiLoadIcons :: proc(fileName: cstring, loadIconsName: bool) -> [^]cstring --- // Load raygui icons file (.rgi) into internal icons data + GuiDrawIcon :: proc(iconId: GuiIconName, posX, posY: c.int, pixelSize: c.int, color: Color) --- // Draw icon using pixel size at specified position + + + // Controls + //---------------------------------------------------------------------------------------------------------- + // Container/separator controls, useful for controls organization + + GuiWindowBox :: proc(bounds: Rectangle, title: cstring) -> c.int --- // Window Box control, shows a window that can be closed + GuiGroupBox :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Group Box control with text name + GuiLine :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Line separator control, could contain text + GuiPanel :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Panel control, useful to group controls + GuiTabBar :: proc(bounds: Rectangle, text: [^]cstring, count: c.int, active: ^c.int) -> c.int --- // Tab Bar control, returns TAB to be closed or -1 + GuiScrollPanel :: proc(bounds: Rectangle, text: cstring, content: Rectangle, scroll: ^Vector2, view: ^Rectangle) -> c.int --- // Scroll Panel control + + // Basic controls set + + GuiLabel :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Label control, shows text + GuiButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Button control, returns true when clicked + GuiLabelButton :: proc(bounds: Rectangle, text: cstring) -> bool --- // Label button control, show true when clicked + GuiToggle :: proc(bounds: Rectangle, text: cstring, active: ^bool) -> c.int --- // Toggle Button control, returns true when active + GuiToggleGroup :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Toggle Group control, returns active toggle index + GuiToggleSlider :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- + GuiCheckBox :: proc(bounds: Rectangle, text: cstring, checked: ^bool) -> bool --- // Check Box control, returns true when active + GuiComboBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int) -> c.int --- // Combo Box control, returns selected item index + + GuiDropdownBox :: proc(bounds: Rectangle, text: cstring, active: ^c.int, editMode: bool) -> bool --- // Dropdown Box control, returns selected item + GuiSpinner :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Spinner control, returns selected value + GuiValueBox :: proc(bounds: Rectangle, text: cstring, value: ^c.int, minValue, maxValue: c.int, editMode: bool) -> c.int --- // Value Box control, updates input text with numbers + GuiTextBox :: proc(bounds: Rectangle, text: cstring, textSize: c.int, editMode: bool) -> bool --- // Text Box control, updates input text + + GuiSlider :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider control, returns selected value + GuiSliderBar :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Slider Bar control, returns selected value + GuiProgressBar :: proc(bounds: Rectangle, textLeft: cstring, textRight: cstring, value: ^f32, minValue: f32, maxValue: f32) -> c.int --- // Progress Bar control, shows current progress value + GuiStatusBar :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Status Bar control, shows info text + GuiDummyRec :: proc(bounds: Rectangle, text: cstring) -> c.int --- // Dummy control for placeholders + GuiGrid :: proc(bounds: Rectangle, text: cstring, spacing: f32, subdivs: c.int, mouseCell: ^Vector2) -> c.int --- // Grid control, returns mouse cell position + + // Advance controls set + GuiListView :: proc(bounds: Rectangle, text: cstring, scrollIndex: ^c.int, active: ^c.int) -> c.int --- // List View control, returns selected list item index + GuiListViewEx :: proc(bounds: Rectangle, text:[^]cstring, count: c.int, scrollIndex: ^c.int, active: ^c.int, focus: ^c.int) -> c.int --- // List View with extended parameters + GuiMessageBox :: proc(bounds: Rectangle, title: cstring, message: cstring, buttons: cstring) -> c.int --- // Message Box control, displays a message + GuiTextInputBox :: proc(bounds: Rectangle, title: cstring, message: cstring, buttons: cstring, text: cstring, textMaxSize: c.int, secretViewActive: ^bool) -> c.int --- // Text Input Box control, ask for text, supports secret + GuiColorPicker :: proc(bounds: Rectangle, text: cstring, color: ^Color) -> c.int --- // Color Picker control (multiple color controls) + GuiColorPanel :: proc(bounds: Rectangle, text: cstring, color: ^Color) -> c.int --- // Color Panel control + GuiColorBarAlpha :: proc(bounds: Rectangle, text: cstring, alpha: ^f32) -> c.int --- // Color Bar Alpha control + GuiColorBarHue :: proc(bounds: Rectangle, text: cstring, value: ^f32) -> c.int --- // Color Bar Hue control + GuiColorPickerHSV :: proc(bounds: Rectangle, text: cstring, colorHsv: ^Vector3) -> c.int --- // Color Picker control that avoids conversion to RGB on each call (multiple color controls) + GuiColorPanelHSV :: proc(bounds: Rectangle, text: cstring, colorHsv: ^Vector3) -> c.int --- // Color Panel control that returns HSV color value, used by GuiColorPickerHSV() + //---------------------------------------------------------------------------------------------------------- +} + +//---------------------------------------------------------------------------------- +// Icons enumeration +//---------------------------------------------------------------------------------- +GuiIconName :: enum c.int { + ICON_NONE = 0, + ICON_FOLDER_FILE_OPEN = 1, + ICON_FILE_SAVE_CLASSIC = 2, + ICON_FOLDER_OPEN = 3, + ICON_FOLDER_SAVE = 4, + ICON_FILE_OPEN = 5, + ICON_FILE_SAVE = 6, + ICON_FILE_EXPORT = 7, + ICON_FILE_ADD = 8, + ICON_FILE_DELETE = 9, + ICON_FILETYPE_TEXT = 10, + ICON_FILETYPE_AUDIO = 11, + ICON_FILETYPE_IMAGE = 12, + ICON_FILETYPE_PLAY = 13, + ICON_FILETYPE_VIDEO = 14, + ICON_FILETYPE_INFO = 15, + ICON_FILE_COPY = 16, + ICON_FILE_CUT = 17, + ICON_FILE_PASTE = 18, + ICON_CURSOR_HAND = 19, + ICON_CURSOR_POINTER = 20, + ICON_CURSOR_CLASSIC = 21, + ICON_PENCIL = 22, + ICON_PENCIL_BIG = 23, + ICON_BRUSH_CLASSIC = 24, + ICON_BRUSH_PAINTER = 25, + ICON_WATER_DROP = 26, + ICON_COLOR_PICKER = 27, + ICON_RUBBER = 28, + ICON_COLOR_BUCKET = 29, + ICON_TEXT_T = 30, + ICON_TEXT_A = 31, + ICON_SCALE = 32, + ICON_RESIZE = 33, + ICON_FILTER_POINT = 34, + ICON_FILTER_BILINEAR = 35, + ICON_CROP = 36, + ICON_CROP_ALPHA = 37, + ICON_SQUARE_TOGGLE = 38, + ICON_SYMMETRY = 39, + ICON_SYMMETRY_HORIZONTAL = 40, + ICON_SYMMETRY_VERTICAL = 41, + ICON_LENS = 42, + ICON_LENS_BIG = 43, + ICON_EYE_ON = 44, + ICON_EYE_OFF = 45, + ICON_FILTER_TOP = 46, + ICON_FILTER = 47, + ICON_TARGET_POINT = 48, + ICON_TARGET_SMALL = 49, + ICON_TARGET_BIG = 50, + ICON_TARGET_MOVE = 51, + ICON_CURSOR_MOVE = 52, + ICON_CURSOR_SCALE = 53, + ICON_CURSOR_SCALE_RIGHT = 54, + ICON_CURSOR_SCALE_LEFT = 55, + ICON_UNDO = 56, + ICON_REDO = 57, + ICON_REREDO = 58, + ICON_MUTATE = 59, + ICON_ROTATE = 60, + ICON_REPEAT = 61, + ICON_SHUFFLE = 62, + ICON_EMPTYBOX = 63, + ICON_TARGET = 64, + ICON_TARGET_SMALL_FILL = 65, + ICON_TARGET_BIG_FILL = 66, + ICON_TARGET_MOVE_FILL = 67, + ICON_CURSOR_MOVE_FILL = 68, + ICON_CURSOR_SCALE_FILL = 69, + ICON_CURSOR_SCALE_RIGHT_FILL = 70, + ICON_CURSOR_SCALE_LEFT_FILL = 71, + ICON_UNDO_FILL = 72, + ICON_REDO_FILL = 73, + ICON_REREDO_FILL = 74, + ICON_MUTATE_FILL = 75, + ICON_ROTATE_FILL = 76, + ICON_REPEAT_FILL = 77, + ICON_SHUFFLE_FILL = 78, + ICON_EMPTYBOX_SMALL = 79, + ICON_BOX = 80, + ICON_BOX_TOP = 81, + ICON_BOX_TOP_RIGHT = 82, + ICON_BOX_RIGHT = 83, + ICON_BOX_BOTTOM_RIGHT = 84, + ICON_BOX_BOTTOM = 85, + ICON_BOX_BOTTOM_LEFT = 86, + ICON_BOX_LEFT = 87, + ICON_BOX_TOP_LEFT = 88, + ICON_BOX_CENTER = 89, + ICON_BOX_CIRCLE_MASK = 90, + ICON_POT = 91, + ICON_ALPHA_MULTIPLY = 92, + ICON_ALPHA_CLEAR = 93, + ICON_DITHERING = 94, + ICON_MIPMAPS = 95, + ICON_BOX_GRID = 96, + ICON_GRID = 97, + ICON_BOX_CORNERS_SMALL = 98, + ICON_BOX_CORNERS_BIG = 99, + ICON_FOUR_BOXES = 100, + ICON_GRID_FILL = 101, + ICON_BOX_MULTISIZE = 102, + ICON_ZOOM_SMALL = 103, + ICON_ZOOM_MEDIUM = 104, + ICON_ZOOM_BIG = 105, + ICON_ZOOM_ALL = 106, + ICON_ZOOM_CENTER = 107, + ICON_BOX_DOTS_SMALL = 108, + ICON_BOX_DOTS_BIG = 109, + ICON_BOX_CONCENTRIC = 110, + ICON_BOX_GRID_BIG = 111, + ICON_OK_TICK = 112, + ICON_CROSS = 113, + ICON_ARROW_LEFT = 114, + ICON_ARROW_RIGHT = 115, + ICON_ARROW_DOWN = 116, + ICON_ARROW_UP = 117, + ICON_ARROW_LEFT_FILL = 118, + ICON_ARROW_RIGHT_FILL = 119, + ICON_ARROW_DOWN_FILL = 120, + ICON_ARROW_UP_FILL = 121, + ICON_AUDIO = 122, + ICON_FX = 123, + ICON_WAVE = 124, + ICON_WAVE_SINUS = 125, + ICON_WAVE_SQUARE = 126, + ICON_WAVE_TRIANGULAR = 127, + ICON_CROSS_SMALL = 128, + ICON_PLAYER_PREVIOUS = 129, + ICON_PLAYER_PLAY_BACK = 130, + ICON_PLAYER_PLAY = 131, + ICON_PLAYER_PAUSE = 132, + ICON_PLAYER_STOP = 133, + ICON_PLAYER_NEXT = 134, + ICON_PLAYER_RECORD = 135, + ICON_MAGNET = 136, + ICON_LOCK_CLOSE = 137, + ICON_LOCK_OPEN = 138, + ICON_CLOCK = 139, + ICON_TOOLS = 140, + ICON_GEAR = 141, + ICON_GEAR_BIG = 142, + ICON_BIN = 143, + ICON_HAND_POINTER = 144, + ICON_LASER = 145, + ICON_COIN = 146, + ICON_EXPLOSION = 147, + ICON_1UP = 148, + ICON_PLAYER = 149, + ICON_PLAYER_JUMP = 150, + ICON_KEY = 151, + ICON_DEMON = 152, + ICON_TEXT_POPUP = 153, + ICON_GEAR_EX = 154, + ICON_CRACK = 155, + ICON_CRACK_POINTS = 156, + ICON_STAR = 157, + ICON_DOOR = 158, + ICON_EXIT = 159, + ICON_MODE_2D = 160, + ICON_MODE_3D = 161, + ICON_CUBE = 162, + ICON_CUBE_FACE_TOP = 163, + ICON_CUBE_FACE_LEFT = 164, + ICON_CUBE_FACE_FRONT = 165, + ICON_CUBE_FACE_BOTTOM = 166, + ICON_CUBE_FACE_RIGHT = 167, + ICON_CUBE_FACE_BACK = 168, + ICON_CAMERA = 169, + ICON_SPECIAL = 170, + ICON_LINK_NET = 171, + ICON_LINK_BOXES = 172, + ICON_LINK_MULTI = 173, + ICON_LINK = 174, + ICON_LINK_BROKE = 175, + ICON_TEXT_NOTES = 176, + ICON_NOTEBOOK = 177, + ICON_SUITCASE = 178, + ICON_SUITCASE_ZIP = 179, + ICON_MAILBOX = 180, + ICON_MONITOR = 181, + ICON_PRINTER = 182, + ICON_PHOTO_CAMERA = 183, + ICON_PHOTO_CAMERA_FLASH = 184, + ICON_HOUSE = 185, + ICON_HEART = 186, + ICON_CORNER = 187, + ICON_VERTICAL_BARS = 188, + ICON_VERTICAL_BARS_FILL = 189, + ICON_LIFE_BARS = 190, + ICON_INFO = 191, + ICON_CROSSLINE = 192, + ICON_HELP = 193, + ICON_FILETYPE_ALPHA = 194, + ICON_FILETYPE_HOME = 195, + ICON_LAYERS_VISIBLE = 196, + ICON_LAYERS = 197, + ICON_WINDOW = 198, + ICON_HIDPI = 199, + ICON_FILETYPE_BINARY = 200, + ICON_HEX = 201, + ICON_SHIELD = 202, + ICON_FILE_NEW = 203, + ICON_FOLDER_ADD = 204, + ICON_ALARM = 205, + ICON_CPU = 206, + ICON_ROM = 207, + ICON_STEP_OVER = 208, + ICON_STEP_INTO = 209, + ICON_STEP_OUT = 210, + ICON_RESTART = 211, + ICON_BREAKPOINT_ON = 212, + ICON_BREAKPOINT_OFF = 213, + ICON_BURGER_MENU = 214, + ICON_CASE_SENSITIVE = 215, + ICON_REG_EXP = 216, + ICON_FOLDER = 217, + ICON_FILE = 218, + ICON_SAND_TIMER = 219, + ICON_220 = 220, + ICON_221 = 221, + ICON_222 = 222, + ICON_223 = 223, + ICON_224 = 224, + ICON_225 = 225, + ICON_226 = 226, + ICON_227 = 227, + ICON_228 = 228, + ICON_229 = 229, + ICON_230 = 230, + ICON_231 = 231, + ICON_232 = 232, + ICON_233 = 233, + ICON_234 = 234, + ICON_235 = 235, + ICON_236 = 236, + ICON_237 = 237, + ICON_238 = 238, + ICON_239 = 239, + ICON_240 = 240, + ICON_241 = 241, + ICON_242 = 242, + ICON_243 = 243, + ICON_244 = 244, + ICON_245 = 245, + ICON_246 = 246, + ICON_247 = 247, + ICON_248 = 248, + ICON_249 = 249, + ICON_250 = 250, + ICON_251 = 251, + ICON_252 = 252, + ICON_253 = 253, + ICON_254 = 254, + ICON_255 = 255, } diff --git a/libs/raylib/raylib.odin b/libs/raylib/raylib.odin index b3daab9..e337724 100644 --- a/libs/raylib/raylib.odin +++ b/libs/raylib/raylib.odin @@ -119,40 +119,40 @@ VERSION_MINOR :: 5 VERSION_PATCH :: 0 VERSION :: "5.5" -PI :: 3.14159265358979323846 -DEG2RAD :: PI / 180.0 -RAD2DEG :: 180.0 / PI +PI :: 3.14159265358979323846 +DEG2RAD :: PI/180.0 +RAD2DEG :: 180.0/PI // Some Basic Colors // NOTE: Custom raylib color palette for amazing visuals on WHITE background -LIGHTGRAY :: Color{200, 200, 200, 255} // Light Gray -GRAY :: Color{130, 130, 130, 255} // Gray -DARKGRAY :: Color{80, 80, 80, 255} // Dark Gray -YELLOW :: Color{253, 249, 0, 255} // Yellow -GOLD :: Color{255, 203, 0, 255} // Gold -ORANGE :: Color{255, 161, 0, 255} // Orange -PINK :: Color{255, 109, 194, 255} // Pink -RED :: Color{230, 41, 55, 255} // Red -MAROON :: Color{190, 33, 55, 255} // Maroon -GREEN :: Color{0, 228, 48, 255} // Green -LIME :: Color{0, 158, 47, 255} // Lime -DARKGREEN :: Color{0, 117, 44, 255} // Dark Green -SKYBLUE :: Color{102, 191, 255, 255} // Sky Blue -BLUE :: Color{0, 121, 241, 255} // Blue -DARKBLUE :: Color{0, 82, 172, 255} // Dark Blue -PURPLE :: Color{200, 122, 255, 255} // Purple -VIOLET :: Color{135, 60, 190, 255} // Violet -DARKPURPLE :: Color{112, 31, 126, 255} // Dark Purple -BEIGE :: Color{211, 176, 131, 255} // Beige -BROWN :: Color{127, 106, 79, 255} // Brown -DARKBROWN :: Color{76, 63, 47, 255} // Dark Brown +LIGHTGRAY :: Color{ 200, 200, 200, 255 } // Light Gray +GRAY :: Color{ 130, 130, 130, 255 } // Gray +DARKGRAY :: Color{ 80, 80, 80, 255 } // Dark Gray +YELLOW :: Color{ 253, 249, 0, 255 } // Yellow +GOLD :: Color{ 255, 203, 0, 255 } // Gold +ORANGE :: Color{ 255, 161, 0, 255 } // Orange +PINK :: Color{ 255, 109, 194, 255 } // Pink +RED :: Color{ 230, 41, 55, 255 } // Red +MAROON :: Color{ 190, 33, 55, 255 } // Maroon +GREEN :: Color{ 0, 228, 48, 255 } // Green +LIME :: Color{ 0, 158, 47, 255 } // Lime +DARKGREEN :: Color{ 0, 117, 44, 255 } // Dark Green +SKYBLUE :: Color{ 102, 191, 255, 255 } // Sky Blue +BLUE :: Color{ 0, 121, 241, 255 } // Blue +DARKBLUE :: Color{ 0, 82, 172, 255 } // Dark Blue +PURPLE :: Color{ 200, 122, 255, 255 } // Purple +VIOLET :: Color{ 135, 60, 190, 255 } // Violet +DARKPURPLE :: Color{ 112, 31, 126, 255 } // Dark Purple +BEIGE :: Color{ 211, 176, 131, 255 } // Beige +BROWN :: Color{ 127, 106, 79, 255 } // Brown +DARKBROWN :: Color{ 76, 63, 47, 255 } // Dark Brown -WHITE :: Color{255, 255, 255, 255} // White -BLACK :: Color{0, 0, 0, 255} // Black -BLANK :: Color{0, 0, 0, 0} // Blank (Transparent) -MAGENTA :: Color{255, 0, 255, 255} // Magenta -RAYWHITE :: Color{245, 245, 245, 255} // My own White (raylib logo) +WHITE :: Color{ 255, 255, 255, 255 } // White +BLACK :: Color{ 0, 0, 0, 255 } // Black +BLANK :: Color{ 0, 0, 0, 0 } // Blank (Transparent) +MAGENTA :: Color{ 255, 0, 255, 255 } // Magenta +RAYWHITE :: Color{ 245, 245, 245, 255 } // My own White (raylib logo) // Vector2 type Vector2 :: [2]f32 @@ -165,7 +165,7 @@ Vector4 :: [4]f32 Quaternion :: quaternion128 // Matrix type (right handed, stored row major) -Matrix :: # row_major matrix[4, 4]f32 +Matrix :: #row_major matrix[4, 4]f32 // Color, 4 components, R8G8B8A8 (32bit) @@ -175,30 +175,30 @@ Color :: distinct [4]u8 // Rectangle type Rectangle :: struct { - x: f32, // Rectangle top-left corner position x - y: f32, // Rectangle top-left corner position y - width: f32, // Rectangle width - height: f32, // Rectangle height + x: f32, // Rectangle top-left corner position x + y: f32, // Rectangle top-left corner position y + width: f32, // Rectangle width + height: f32, // Rectangle height } // Image type, bpp always RGBA (32bit) // NOTE: Data stored in CPU memory (RAM) Image :: struct { - data: rawptr, // Image raw data - width: c.int, // Image base width - height: c.int, // Image base height - mipmaps: c.int, // Mipmap levels, 1 by default - format: PixelFormat, // Data format (PixelFormat type) + data: rawptr, // Image raw data + width: c.int, // Image base width + height: c.int, // Image base height + mipmaps: c.int, // Mipmap levels, 1 by default + format: PixelFormat, // Data format (PixelFormat type) } // Texture type // NOTE: Data stored in GPU memory Texture :: struct { - id: c.uint, // OpenGL texture id - width: c.int, // Texture base width - height: c.int, // Texture base height - mipmaps: c.int, // Mipmap levels, 1 by default - format: PixelFormat, // Data format (PixelFormat type) + id: c.uint, // OpenGL texture id + width: c.int, // Texture base width + height: c.int, // Texture base height + mipmaps: c.int, // Mipmap levels, 1 by default + format: PixelFormat, // Data format (PixelFormat type) } // Texture2D type, same as Texture @@ -209,246 +209,249 @@ TextureCubemap :: Texture // RenderTexture type, for texture rendering RenderTexture :: struct { - id: c.uint, // OpenGL framebuffer object id - texture: Texture, // Color buffer attachment texture - depth: Texture, // Depth buffer attachment texture -} + id: c.uint, // OpenGL framebuffer object id + texture: Texture, // Color buffer attachment texture + depth: Texture, // Depth buffer attachment texture +} // RenderTexture2D type, same as RenderTexture RenderTexture2D :: RenderTexture // N-Patch layout info NPatchInfo :: struct { - source: Rectangle, // Texture source rectangle - left: c.int, // Left border offset - top: c.int, // Top border offset - right: c.int, // Right border offset - bottom: c.int, // Bottom border offset - layout: NPatchLayout, // Layout of the n-patch: 3x3, 1x3 or 3x1 + source: Rectangle, // Texture source rectangle + left: c.int, // Left border offset + top: c.int, // Top border offset + right: c.int, // Right border offset + bottom: c.int, // Bottom border offset + layout: NPatchLayout, // Layout of the n-patch: 3x3, 1x3 or 3x1 } // Font character info GlyphInfo :: struct { - value: rune, // Character value (Unicode) - offsetX: c.int, // Character offset X when drawing - offsetY: c.int, // Character offset Y when drawing - advanceX: c.int, // Character advance position X - image: Image, // Character image data -} + value: rune, // Character value (Unicode) + offsetX: c.int, // Character offset X when drawing + offsetY: c.int, // Character offset Y when drawing + advanceX: c.int, // Character advance position X + image: Image, // Character image data +} // Font type, includes texture and charSet array data Font :: struct { - baseSize: c.int, // Base size (default chars height) - glyphCount: c.int, // Number of characters - glyphPadding: c.int, // Padding around the chars - texture: Texture2D, // Characters texture atlas - recs: [^]Rectangle, // Characters rectangles in texture - glyphs: [^]GlyphInfo, // Characters info data + baseSize: c.int, // Base size (default chars height) + glyphCount: c.int, // Number of characters + glyphPadding: c.int, // Padding around the chars + texture: Texture2D, // Characters texture atlas + recs: [^]Rectangle, // Characters rectangles in texture + glyphs: [^]GlyphInfo, // Characters info data } // Camera type, defines a camera position/orientation in 3d space Camera3D :: struct { - position: Vector3, // Camera position - target: Vector3, // Camera target it looks-at - up: Vector3, // Camera up vector (rotation over its axis) - fovy: f32, // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic - projection: CameraProjection, // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC + position: Vector3, // Camera position + target: Vector3, // Camera target it looks-at + up: Vector3, // Camera up vector (rotation over its axis) + fovy: f32, // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic + projection: CameraProjection, // Camera projection: `.PERSPECTIVE` or `.ORTHOGRAPHIC` } -Camera :: Camera3D // Camera type fallback, defaults to Camera3D +Camera :: Camera3D // Camera type fallback, defaults to Camera3D // Camera2D type, defines a 2d camera Camera2D :: struct { - offset: Vector2, // Camera offset (displacement from target) - target: Vector2, // Camera target (rotation and zoom origin) - rotation: f32, // Camera rotation in degrees - zoom: f32, // Camera zoom (scaling), should be 1.0f by default + offset: Vector2, // Camera offset (displacement from target) + target: Vector2, // Camera target (rotation and zoom origin) + rotation: f32, // Camera rotation in degrees + zoom: f32, // Camera zoom (scaling), should be 1.0f by default } // Vertex data defining a mesh // NOTE: Data stored in CPU memory (and GPU) Mesh :: struct { - vertexCount: c.int, // Number of vertices stored in arrays - triangleCount: c.int, // Number of triangles stored (indexed or not) + vertexCount: c.int, // Number of vertices stored in arrays + triangleCount: c.int, // Number of triangles stored (indexed or not) // Default vertex data - vertices: [^]f32, // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) - texcoords: [^]f32, // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - texcoords2: [^]f32, // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5) - normals: [^]f32, // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) - tangents: [^]f32, // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) - colors: [^]u8, // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - indices: [^]u16, // Vertex indices (in case vertex data comes indexed) + vertices: [^]f32, // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + texcoords: [^]f32, // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + texcoords2: [^]f32, // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5) + normals: [^]f32, // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2) + tangents: [^]f32, // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4) + colors: [^]u8, // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + indices: [^]u16, // Vertex indices (in case vertex data comes indexed) // Animation vertex data - animVertices: [^]f32, // Animated vertex positions (after bones transformations) - animNormals: [^]f32, // Animated normals (after bones transformations) - boneIds: [^]u8, // Vertex bone ids, up to 4 bones influence by vertex (skinning) - boneWeights: [^]f32, // Vertex bone weight, up to 4 bones influence by vertex (skinning) - boneMatrices: [^]Matrix, // Bones animated transformation matrices - boneCount: c.int, // Number of bones + animVertices: [^]f32, // Animated vertex positions (after bones transformations) + animNormals: [^]f32, // Animated normals (after bones transformations) + boneIds: [^]u8, // Vertex bone ids, up to 4 bones influence by vertex (skinning) + boneWeights: [^]f32, // Vertex bone weight, up to 4 bones influence by vertex (skinning) + boneMatrices: [^]Matrix, // Bones animated transformation matrices + boneCount: c.int, // Number of bones // OpenGL identifiers - vaoId: u32, // OpenGL Vertex Array Object id - vboId: [^]u32, // OpenGL Vertex Buffer Objects id (default vertex data) + vaoId: u32, // OpenGL Vertex Array Object id + vboId: [^]u32, // OpenGL Vertex Buffer Objects id (default vertex data) } // Shader type (generic) Shader :: struct { - id: c.uint, // Shader program id - locs: [^]c.int, // Shader locations array (MAX_SHADER_LOCATIONS) + id: c.uint, // Shader program id + locs: [^]c.int, // Shader locations array (MAX_SHADER_LOCATIONS) } // Material texture map MaterialMap :: struct { - texture: Texture2D, // Material map texture - color: Color, // Material map color - value: f32, // Material map value + texture: Texture2D, // Material map texture + color: Color, // Material map color + value: f32, // Material map value } // Material type (generic) Material :: struct { - shader: Shader, // Material shader - maps: [^]MaterialMap, // Material maps array (MAX_MATERIAL_MAPS) - params: [4]f32, // Material generic parameters (if required) + shader: Shader, // Material shader + maps: [^]MaterialMap, // Material maps array (MAX_MATERIAL_MAPS) + params: [4]f32, // Material generic parameters (if required) } // Transformation properties Transform :: struct { - translation: Vector3, // Translation - rotation: Quaternion, // Rotation - scale: Vector3, // Scale + translation: Vector3, // Translation + rotation: Quaternion, // Rotation + scale: Vector3, // Scale } // Bone information BoneInfo :: struct { name: [32]byte `fmt:"s,0"`, // Bone name - parent: c.int, // Bone parent + parent: c.int, // Bone parent } // Model type -Model :: struct #align (align_of(uintptr)) { - transform: Matrix, // Local transform matrix - meshCount: c.int, // Number of meshes - materialCount: c.int, // Number of materials - meshes: [^]Mesh, // Meshes array - materials: [^]Material, // Materials array - meshMaterial: [^]c.int, // Mesh material number +Model :: struct #align(align_of(uintptr)) { + transform: Matrix, // Local transform matrix + + meshCount: c.int, // Number of meshes + materialCount: c.int, // Number of materials + meshes: [^]Mesh, // Meshes array + materials: [^]Material, // Materials array + meshMaterial: [^]c.int, // Mesh material number // Animation data - boneCount: c.int, // Number of bones - bones: [^]BoneInfo, // Bones information (skeleton) - bindPose: [^]Transform, // Bones base transformation (pose) + boneCount: c.int, // Number of bones + bones: [^]BoneInfo, // Bones information (skeleton) + bindPose: [^]Transform, // Bones base transformation (pose) } // Model animation ModelAnimation :: struct { - boneCount: c.int, // Number of bones - frameCount: c.int, // Number of animation frames - bones: [^]BoneInfo, // Bones information (skeleton) - framePoses: [^][^]Transform, // Poses array by frame + boneCount: c.int, // Number of bones + frameCount: c.int, // Number of animation frames + bones: [^]BoneInfo, // Bones information (skeleton) + framePoses: [^][^]Transform, // Poses array by frame name: [32]byte `fmt:"s,0"`, // Animation name } // Ray type (useful for raycast) Ray :: struct { - position: Vector3, // Ray position (origin) - direction: Vector3, // Ray direction (normalized) + position: Vector3, // Ray position (origin) + direction: Vector3, // Ray direction (normalized) } // RayCollision, ray hit information RayCollision :: struct { - hit: bool, // Did the ray hit something? - distance: f32, // Distance to nearest hit - point: Vector3, // Point of nearest hit - normal: Vector3, // Surface normal of hit + hit: bool, // Did the ray hit something? + distance: f32, // Distance to nearest hit + point: Vector3, // Point of nearest hit + normal: Vector3, // Surface normal of hit } // Bounding box type BoundingBox :: struct { - min: Vector3, // Minimum vertex box-corner - max: Vector3, // Maximum vertex box-corner + min: Vector3, // Minimum vertex box-corner + max: Vector3, // Maximum vertex box-corner } // Wave type, defines audio wave data Wave :: struct { - frameCount: c.uint, // Total number of frames (considering channels) - sampleRate: c.uint, // Frequency (samples per second) - sampleSize: c.uint, // Bit depth (bits per sample): 8, 16, 32 (24 not supported) - channels: c.uint, // Number of channels (1-mono, 2-stereo) - data: rawptr, // Buffer data pointer + frameCount: c.uint, // Total number of frames (considering channels) + sampleRate: c.uint, // Frequency (samples per second) + sampleSize: c.uint, // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + channels: c.uint, // Number of channels (1-mono, 2-stereo) + data: rawptr, // Buffer data pointer } // Audio stream type // NOTE: Actual structs are defined internally in raudio module AudioStream :: struct { - buffer: rawptr, // Pointer to internal data used by the audio system - processor: rawptr, // Pointer to internal data processor, useful for audio effects - sampleRate: c.uint, // Frequency (samples per second) - sampleSize: c.uint, // Bit depth (bits per sample): 8, 16, 32 (24 not supported) - channels: c.uint, // Number of channels (1-mono, 2-stereo) + buffer: rawptr, // Pointer to internal data used by the audio system + processor: rawptr, // Pointer to internal data processor, useful for audio effects + + sampleRate: c.uint, // Frequency (samples per second) + sampleSize: c.uint, // Bit depth (bits per sample): 8, 16, 32 (24 not supported) + channels: c.uint, // Number of channels (1-mono, 2-stereo) } // Sound source type Sound :: struct { - using stream: AudioStream, // Audio stream - frameCount: c.uint, // Total number of frames (considering channels) + using stream: AudioStream, // Audio stream + frameCount: c.uint, // Total number of frames (considering channels) } // Music stream type (audio file streaming from memory) // NOTE: Anything longer than ~10 seconds should be streamed Music :: struct { - using stream: AudioStream, // Audio stream - frameCount: c.uint, // Total number of frames (considering channels) - looping: bool, // Music looping enable - ctxType: c.int, // Type of music context (audio filetype) - ctxData: rawptr, // Audio context data, depends on type + using stream: AudioStream, // Audio stream + frameCount: c.uint, // Total number of frames (considering channels) + looping: bool, // Music looping enable + + ctxType: c.int, // Type of music context (audio filetype) + ctxData: rawptr, // Audio context data, depends on type } // Head-Mounted-Display device parameters VrDeviceInfo :: struct { - hResolution: c.int, // Horizontal resolution in pixels - vResolution: c.int, // Vertical resolution in pixels - hScreenSize: f32, // Horizontal size in meters - vScreenSize: f32, // Vertical size in meters - eyeToScreenDistance: f32, // Distance between eye and display in meters - lensSeparationDistance: f32, // Lens separation distance in meters - interpupillaryDistance: f32, // IPD (distance between pupils) in meters - lensDistortionValues: [4]f32, // Lens distortion constant parameters - chromaAbCorrection: [4]f32, // Chromatic aberration correction parameters + hResolution: c.int, // Horizontal resolution in pixels + vResolution: c.int, // Vertical resolution in pixels + hScreenSize: f32, // Horizontal size in meters + vScreenSize: f32, // Vertical size in meters + eyeToScreenDistance: f32, // Distance between eye and display in meters + lensSeparationDistance: f32, // Lens separation distance in meters + interpupillaryDistance: f32, // IPD (distance between pupils) in meters + lensDistortionValues: [4]f32, // Lens distortion constant parameters + chromaAbCorrection: [4]f32, // Chromatic aberration correction parameters } // VR Stereo rendering configuration for simulator -VrStereoConfig :: struct #align (4) { - projection: [2]Matrix, // VR projection matrices (per eye) - viewOffset: [2]Matrix, // VR view offset matrices (per eye) - leftLensCenter: [2]f32, // VR left lens center - rightLensCenter: [2]f32, // VR right lens center - leftScreenCenter: [2]f32, // VR left screen center - rightScreenCenter: [2]f32, // VR right screen center - scale: [2]f32, // VR distortion scale - scaleIn: [2]f32, // VR distortion scale in +VrStereoConfig :: struct #align(4) { + projection: [2]Matrix, // VR projection matrices (per eye) + viewOffset: [2]Matrix, // VR view offset matrices (per eye) + leftLensCenter: [2]f32, // VR left lens center + rightLensCenter: [2]f32, // VR right lens center + leftScreenCenter: [2]f32, // VR left screen center + rightScreenCenter: [2]f32, // VR right screen center + scale: [2]f32, // VR distortion scale + scaleIn: [2]f32, // VR distortion scale in } // File path list FilePathList :: struct { - capacity: c.uint, // Filepaths max entries - count: c.uint, // Filepaths entries count - paths: [^]cstring, // Filepaths entries + capacity: c.uint, // Filepaths max entries + count: c.uint, // Filepaths entries count + paths: [^]cstring, // Filepaths entries } // Automation event AutomationEvent :: struct { - frame: c.uint, // Event frame - type: c.uint, // Event type (AutomationEventType) - params: [4]c.int, // Event parameters (if required) --- + frame: c.uint, // Event frame + type: c.uint, // Event type (AutomationEventType) + params: [4]c.int, // Event parameters (if required) --- } // Automation event list AutomationEventList :: struct { - capacity: c.uint, // Events max entries (MAX_AUTOMATION_EVENTS) - count: c.uint, // Events entries count - events: [^]AutomationEvent, // Events entries + capacity: c.uint, // Events max entries (MAX_AUTOMATION_EVENTS) + count: c.uint, // Events entries count + events: [^]AutomationEvent, // Events entries } //---------------------------------------------------------------------------------- @@ -458,407 +461,418 @@ AutomationEventList :: struct { // NOTE: Every bit registers one state (use it with bit masks) // By default all flags are set to 0 ConfigFlag :: enum c.int { - VSYNC_HINT = 6, // Set to try enabling V-Sync on GPU - FULLSCREEN_MODE = 1, // Set to run program in fullscreen - WINDOW_RESIZABLE = 2, // Set to allow resizable window - WINDOW_UNDECORATED = 3, // Set to disable window decoration (frame and buttons) - WINDOW_HIDDEN = 7, // Set to hide window - WINDOW_MINIMIZED = 9, // Set to minimize window (iconify) - WINDOW_MAXIMIZED = 10, // Set to maximize window (expanded to monitor) - WINDOW_UNFOCUSED = 11, // Set to window non focused - WINDOW_TOPMOST = 12, // Set to window always on top - WINDOW_ALWAYS_RUN = 8, // Set to allow windows running while minimized - WINDOW_TRANSPARENT = 4, // Set to allow transparent framebuffer - WINDOW_HIGHDPI = 13, // Set to support HighDPI - WINDOW_MOUSE_PASSTHROUGH = 14, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED - BORDERLESS_WINDOWED_MODE = 15, // Set to run program in borderless windowed mode - MSAA_4X_HINT = 5, // Set to try enabling MSAA 4X - INTERLACED_HINT = 16, // Set to try enabling interlaced video format (for V3D) + VSYNC_HINT = 6, // Set to try enabling V-Sync on GPU + FULLSCREEN_MODE = 1, // Set to run program in fullscreen + WINDOW_RESIZABLE = 2, // Set to allow resizable window + WINDOW_UNDECORATED = 3, // Set to disable window decoration (frame and buttons) + WINDOW_HIDDEN = 7, // Set to hide window + WINDOW_MINIMIZED = 9, // Set to minimize window (iconify) + WINDOW_MAXIMIZED = 10, // Set to maximize window (expanded to monitor) + WINDOW_UNFOCUSED = 11, // Set to window non focused + WINDOW_TOPMOST = 12, // Set to window always on top + WINDOW_ALWAYS_RUN = 8, // Set to allow windows running while minimized + WINDOW_TRANSPARENT = 4, // Set to allow transparent framebuffer + WINDOW_HIGHDPI = 13, // Set to support HighDPI + WINDOW_MOUSE_PASSTHROUGH = 14, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + BORDERLESS_WINDOWED_MODE = 15, // Set to run program in borderless windowed mode + MSAA_4X_HINT = 5, // Set to try enabling MSAA 4X + INTERLACED_HINT = 16, // Set to try enabling interlaced video format (for V3D) } -ConfigFlags :: distinct bit_set[ConfigFlag;c.int] +ConfigFlags :: distinct bit_set[ConfigFlag; c.int] // Trace log level TraceLogLevel :: enum c.int { - ALL = 0, // Display all logs - TRACE, // Trace logging, intended for internal use only - DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds - INFO, // Info logging, used for program execution info - WARNING, // Warning logging, used on recoverable failures - ERROR, // Error logging, used on unrecoverable failures - FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) - NONE, // Disable logging + ALL = 0, // Display all logs + TRACE, // Trace logging, intended for internal use only + DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds + INFO, // Info logging, used for program execution info + WARNING, // Warning logging, used on recoverable failures + ERROR, // Error logging, used on unrecoverable failures + FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) + NONE, // Disable logging } // Keyboard keys (US keyboard layout) // NOTE: Use GetKeyPressed() to allow redefining // required keys for alternative layouts KeyboardKey :: enum c.int { - KEY_NULL = 0, // Key: NULL, used for no key pressed + KEY_NULL = 0, // Key: NULL, used for no key pressed // Alphanumeric keys - APOSTROPHE = 39, // Key: ' - COMMA = 44, // Key: , - MINUS = 45, // Key: - - PERIOD = 46, // Key: . - SLASH = 47, // Key: / - ZERO = 48, // Key: 0 - ONE = 49, // Key: 1 - TWO = 50, // Key: 2 - THREE = 51, // Key: 3 - FOUR = 52, // Key: 4 - FIVE = 53, // Key: 5 - SIX = 54, // Key: 6 - SEVEN = 55, // Key: 7 - EIGHT = 56, // Key: 8 - NINE = 57, // Key: 9 - SEMICOLON = 59, // Key: ; - EQUAL = 61, // Key: = - A = 65, // Key: A | a - B = 66, // Key: B | b - C = 67, // Key: C | c - D = 68, // Key: D | d - E = 69, // Key: E | e - F = 70, // Key: F | f - G = 71, // Key: G | g - H = 72, // Key: H | h - I = 73, // Key: I | i - J = 74, // Key: J | j - K = 75, // Key: K | k - L = 76, // Key: L | l - M = 77, // Key: M | m - N = 78, // Key: N | n - O = 79, // Key: O | o - P = 80, // Key: P | p - Q = 81, // Key: Q | q - R = 82, // Key: R | r - S = 83, // Key: S | s - T = 84, // Key: T | t - U = 85, // Key: U | u - V = 86, // Key: V | v - W = 87, // Key: W | w - X = 88, // Key: X | x - Y = 89, // Key: Y | y - Z = 90, // Key: Z | z - LEFT_BRACKET = 91, // Key: [ - BACKSLASH = 92, // Key: '\' - RIGHT_BRACKET = 93, // Key: ] - GRAVE = 96, // Key: ` + APOSTROPHE = 39, // Key: ' + COMMA = 44, // Key: , + MINUS = 45, // Key: - + PERIOD = 46, // Key: . + SLASH = 47, // Key: / + ZERO = 48, // Key: 0 + ONE = 49, // Key: 1 + TWO = 50, // Key: 2 + THREE = 51, // Key: 3 + FOUR = 52, // Key: 4 + FIVE = 53, // Key: 5 + SIX = 54, // Key: 6 + SEVEN = 55, // Key: 7 + EIGHT = 56, // Key: 8 + NINE = 57, // Key: 9 + SEMICOLON = 59, // Key: ; + EQUAL = 61, // Key: = + A = 65, // Key: A | a + B = 66, // Key: B | b + C = 67, // Key: C | c + D = 68, // Key: D | d + E = 69, // Key: E | e + F = 70, // Key: F | f + G = 71, // Key: G | g + H = 72, // Key: H | h + I = 73, // Key: I | i + J = 74, // Key: J | j + K = 75, // Key: K | k + L = 76, // Key: L | l + M = 77, // Key: M | m + N = 78, // Key: N | n + O = 79, // Key: O | o + P = 80, // Key: P | p + Q = 81, // Key: Q | q + R = 82, // Key: R | r + S = 83, // Key: S | s + T = 84, // Key: T | t + U = 85, // Key: U | u + V = 86, // Key: V | v + W = 87, // Key: W | w + X = 88, // Key: X | x + Y = 89, // Key: Y | y + Z = 90, // Key: Z | z + LEFT_BRACKET = 91, // Key: [ + BACKSLASH = 92, // Key: '\' + RIGHT_BRACKET = 93, // Key: ] + GRAVE = 96, // Key: ` // Function keys - SPACE = 32, // Key: Space - ESCAPE = 256, // Key: Esc - ENTER = 257, // Key: Enter - TAB = 258, // Key: Tab - BACKSPACE = 259, // Key: Backspace - INSERT = 260, // Key: Ins - DELETE = 261, // Key: Del - RIGHT = 262, // Key: Cursor right - LEFT = 263, // Key: Cursor left - DOWN = 264, // Key: Cursor down - UP = 265, // Key: Cursor up - PAGE_UP = 266, // Key: Page up - PAGE_DOWN = 267, // Key: Page down - HOME = 268, // Key: Home - END = 269, // Key: End - CAPS_LOCK = 280, // Key: Caps lock - SCROLL_LOCK = 281, // Key: Scroll down - NUM_LOCK = 282, // Key: Num lock - PRINT_SCREEN = 283, // Key: Print screen - PAUSE = 284, // Key: Pause - F1 = 290, // Key: F1 - F2 = 291, // Key: F2 - F3 = 292, // Key: F3 - F4 = 293, // Key: F4 - F5 = 294, // Key: F5 - F6 = 295, // Key: F6 - F7 = 296, // Key: F7 - F8 = 297, // Key: F8 - F9 = 298, // Key: F9 - F10 = 299, // Key: F10 - F11 = 300, // Key: F11 - F12 = 301, // Key: F12 - LEFT_SHIFT = 340, // Key: Shift left - LEFT_CONTROL = 341, // Key: Control left - LEFT_ALT = 342, // Key: Alt left - LEFT_SUPER = 343, // Key: Super left - RIGHT_SHIFT = 344, // Key: Shift right - RIGHT_CONTROL = 345, // Key: Control right - RIGHT_ALT = 346, // Key: Alt right - RIGHT_SUPER = 347, // Key: Super right - KB_MENU = 348, // Key: KB menu + SPACE = 32, // Key: Space + ESCAPE = 256, // Key: Esc + ENTER = 257, // Key: Enter + TAB = 258, // Key: Tab + BACKSPACE = 259, // Key: Backspace + INSERT = 260, // Key: Ins + DELETE = 261, // Key: Del + RIGHT = 262, // Key: Cursor right + LEFT = 263, // Key: Cursor left + DOWN = 264, // Key: Cursor down + UP = 265, // Key: Cursor up + PAGE_UP = 266, // Key: Page up + PAGE_DOWN = 267, // Key: Page down + HOME = 268, // Key: Home + END = 269, // Key: End + CAPS_LOCK = 280, // Key: Caps lock + SCROLL_LOCK = 281, // Key: Scroll down + NUM_LOCK = 282, // Key: Num lock + PRINT_SCREEN = 283, // Key: Print screen + PAUSE = 284, // Key: Pause + F1 = 290, // Key: F1 + F2 = 291, // Key: F2 + F3 = 292, // Key: F3 + F4 = 293, // Key: F4 + F5 = 294, // Key: F5 + F6 = 295, // Key: F6 + F7 = 296, // Key: F7 + F8 = 297, // Key: F8 + F9 = 298, // Key: F9 + F10 = 299, // Key: F10 + F11 = 300, // Key: F11 + F12 = 301, // Key: F12 + LEFT_SHIFT = 340, // Key: Shift left + LEFT_CONTROL = 341, // Key: Control left + LEFT_ALT = 342, // Key: Alt left + LEFT_SUPER = 343, // Key: Super left + RIGHT_SHIFT = 344, // Key: Shift right + RIGHT_CONTROL = 345, // Key: Control right + RIGHT_ALT = 346, // Key: Alt right + RIGHT_SUPER = 347, // Key: Super right + KB_MENU = 348, // Key: KB menu // Keypad keys - KP_0 = 320, // Key: Keypad 0 - KP_1 = 321, // Key: Keypad 1 - KP_2 = 322, // Key: Keypad 2 - KP_3 = 323, // Key: Keypad 3 - KP_4 = 324, // Key: Keypad 4 - KP_5 = 325, // Key: Keypad 5 - KP_6 = 326, // Key: Keypad 6 - KP_7 = 327, // Key: Keypad 7 - KP_8 = 328, // Key: Keypad 8 - KP_9 = 329, // Key: Keypad 9 - KP_DECIMAL = 330, // Key: Keypad . - KP_DIVIDE = 331, // Key: Keypad / - KP_MULTIPLY = 332, // Key: Keypad * - KP_SUBTRACT = 333, // Key: Keypad - - KP_ADD = 334, // Key: Keypad + - KP_ENTER = 335, // Key: Keypad Enter - KP_EQUAL = 336, // Key: Keypad = + KP_0 = 320, // Key: Keypad 0 + KP_1 = 321, // Key: Keypad 1 + KP_2 = 322, // Key: Keypad 2 + KP_3 = 323, // Key: Keypad 3 + KP_4 = 324, // Key: Keypad 4 + KP_5 = 325, // Key: Keypad 5 + KP_6 = 326, // Key: Keypad 6 + KP_7 = 327, // Key: Keypad 7 + KP_8 = 328, // Key: Keypad 8 + KP_9 = 329, // Key: Keypad 9 + KP_DECIMAL = 330, // Key: Keypad . + KP_DIVIDE = 331, // Key: Keypad / + KP_MULTIPLY = 332, // Key: Keypad * + KP_SUBTRACT = 333, // Key: Keypad - + KP_ADD = 334, // Key: Keypad + + KP_ENTER = 335, // Key: Keypad Enter + KP_EQUAL = 336, // Key: Keypad = // Android key buttons - BACK = 4, // Key: Android back button - MENU = 5, // Key: Android menu button - VOLUME_UP = 24, // Key: Android volume up button - VOLUME_DOWN = 25, // Key: Android volume down button + BACK = 4, // Key: Android back button + MENU = 5, // Key: Android menu button + VOLUME_UP = 24, // Key: Android volume up button + VOLUME_DOWN = 25, // Key: Android volume down button } // Mouse buttons MouseButton :: enum c.int { - LEFT = 0, // Mouse button left - RIGHT = 1, // Mouse button right - MIDDLE = 2, // Mouse button middle (pressed wheel) - SIDE = 3, // Mouse button side (advanced mouse device) - EXTRA = 4, // Mouse button extra (advanced mouse device) - FORWARD = 5, // Mouse button fordward (advanced mouse device) - BACK = 6, // Mouse button back (advanced mouse device) + LEFT = 0, // Mouse button left + RIGHT = 1, // Mouse button right + MIDDLE = 2, // Mouse button middle (pressed wheel) + SIDE = 3, // Mouse button side (advanced mouse device) + EXTRA = 4, // Mouse button extra (advanced mouse device) + FORWARD = 5, // Mouse button fordward (advanced mouse device) + BACK = 6, // Mouse button back (advanced mouse device) } // Mouse cursor MouseCursor :: enum c.int { - DEFAULT = 0, // Default pointer shape - ARROW = 1, // Arrow shape - IBEAM = 2, // Text writing cursor shape - CROSSHAIR = 3, // Cross shape - POINTING_HAND = 4, // Pointing hand cursor - RESIZE_EW = 5, // Horizontal resize/move arrow shape - RESIZE_NS = 6, // Vertical resize/move arrow shape - RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape - RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape - RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape - NOT_ALLOWED = 10, // The operation-not-allowed shape + DEFAULT = 0, // Default pointer shape + ARROW = 1, // Arrow shape + IBEAM = 2, // Text writing cursor shape + CROSSHAIR = 3, // Cross shape + POINTING_HAND = 4, // Pointing hand cursor + RESIZE_EW = 5, // Horizontal resize/move arrow shape + RESIZE_NS = 6, // Vertical resize/move arrow shape + RESIZE_NWSE = 7, // Top-left to bottom-right diagonal resize/move arrow shape + RESIZE_NESW = 8, // The top-right to bottom-left diagonal resize/move arrow shape + RESIZE_ALL = 9, // The omnidirectional resize/move cursor shape + NOT_ALLOWED = 10, // The operation-not-allowed shape } // Gamepad buttons GamepadButton :: enum c.int { - UNKNOWN = 0, // Unknown button, just for error checking - LEFT_FACE_UP, // Gamepad left DPAD up button - LEFT_FACE_RIGHT, // Gamepad left DPAD right button - LEFT_FACE_DOWN, // Gamepad left DPAD down button - LEFT_FACE_LEFT, // Gamepad left DPAD left button - RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) - RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B) - RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) - RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X) - LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button - LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button - RIGHT_TRIGGER_1, // Gamepad top/back trigger right (first), it could be a trailing button - RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button - MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) - MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) - MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) - LEFT_THUMB, // Gamepad joystick pressed button left - RIGHT_THUMB, // Gamepad joystick pressed button right + UNKNOWN = 0, // Unknown button, just for error checking + LEFT_FACE_UP, // Gamepad left DPAD up button + LEFT_FACE_RIGHT, // Gamepad left DPAD right button + LEFT_FACE_DOWN, // Gamepad left DPAD down button + LEFT_FACE_LEFT, // Gamepad left DPAD left button + RIGHT_FACE_UP, // Gamepad right button up (i.e. PS3: Triangle, Xbox: Y) + RIGHT_FACE_RIGHT, // Gamepad right button right (i.e. PS3: Circle, Xbox: B) + RIGHT_FACE_DOWN, // Gamepad right button down (i.e. PS3: Cross, Xbox: A) + RIGHT_FACE_LEFT, // Gamepad right button left (i.e. PS3: Square, Xbox: X) + LEFT_TRIGGER_1, // Gamepad top/back trigger left (first), it could be a trailing button + LEFT_TRIGGER_2, // Gamepad top/back trigger left (second), it could be a trailing button + RIGHT_TRIGGER_1, // Gamepad top/back trigger right (first), it could be a trailing button + RIGHT_TRIGGER_2, // Gamepad top/back trigger right (second), it could be a trailing button + MIDDLE_LEFT, // Gamepad center buttons, left one (i.e. PS3: Select) + MIDDLE, // Gamepad center buttons, middle one (i.e. PS3: PS, Xbox: XBOX) + MIDDLE_RIGHT, // Gamepad center buttons, right one (i.e. PS3: Start) + LEFT_THUMB, // Gamepad joystick pressed button left + RIGHT_THUMB, // Gamepad joystick pressed button right } // Gamepad axis GamepadAxis :: enum c.int { - LEFT_X = 0, // Gamepad left stick X axis - LEFT_Y = 1, // Gamepad left stick Y axis - RIGHT_X = 2, // Gamepad right stick X axis - RIGHT_Y = 3, // Gamepad right stick Y axis - LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] - RIGHT_TRIGGER = 5, // Gamepad back trigger right, pressure level: [1..-1] + LEFT_X = 0, // Gamepad left stick X axis + LEFT_Y = 1, // Gamepad left stick Y axis + RIGHT_X = 2, // Gamepad right stick X axis + RIGHT_Y = 3, // Gamepad right stick Y axis + LEFT_TRIGGER = 4, // Gamepad back trigger left, pressure level: [1..-1] + RIGHT_TRIGGER = 5, // Gamepad back trigger right, pressure level: [1..-1] } // Material map index MaterialMapIndex :: enum c.int { - ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) - METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) - NORMAL, // Normal material - ROUGHNESS, // Roughness material - OCCLUSION, // Ambient occlusion material - EMISSION, // Emission material - HEIGHT, // Heightmap material - CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) - BRDF, // Brdf material + ALBEDO = 0, // Albedo material (same as: MATERIAL_MAP_DIFFUSE) + METALNESS, // Metalness material (same as: MATERIAL_MAP_SPECULAR) + NORMAL, // Normal material + ROUGHNESS, // Roughness material + OCCLUSION, // Ambient occlusion material + EMISSION, // Emission material + HEIGHT, // Heightmap material + CUBEMAP, // Cubemap material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + IRRADIANCE, // Irradiance material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + PREFILTER, // Prefilter material (NOTE: Uses GL_TEXTURE_CUBE_MAP) + BRDF, // Brdf material } // Shader location index ShaderLocationIndex :: enum c.int { - VERTEX_POSITION = 0, // Shader location: vertex attribute: position - VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 - VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 - VERTEX_NORMAL, // Shader location: vertex attribute: normal - VERTEX_TANGENT, // Shader location: vertex attribute: tangent - VERTEX_COLOR, // Shader location: vertex attribute: color - MATRIX_MVP, // Shader location: matrix uniform: model-view-projection - MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) - MATRIX_PROJECTION, // Shader location: matrix uniform: projection - MATRIX_MODEL, // Shader location: matrix uniform: model (transform) - MATRIX_NORMAL, // Shader location: matrix uniform: normal - VECTOR_VIEW, // Shader location: vector uniform: view - COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color - COLOR_SPECULAR, // Shader location: vector uniform: specular color - COLOR_AMBIENT, // Shader location: vector uniform: ambient color - MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) - MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) - MAP_NORMAL, // Shader location: sampler2d texture: normal - MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness - MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion - MAP_EMISSION, // Shader location: sampler2d texture: emission - MAP_HEIGHT, // Shader location: sampler2d texture: height - MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap - MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance - MAP_PREFILTER, // Shader location: samplerCube texture: prefilter - MAP_BRDF, // Shader location: sampler2d texture: brdf - VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds - VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights - BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices + VERTEX_POSITION = 0, // Shader location: vertex attribute: position + VERTEX_TEXCOORD01, // Shader location: vertex attribute: texcoord01 + VERTEX_TEXCOORD02, // Shader location: vertex attribute: texcoord02 + VERTEX_NORMAL, // Shader location: vertex attribute: normal + VERTEX_TANGENT, // Shader location: vertex attribute: tangent + VERTEX_COLOR, // Shader location: vertex attribute: color + MATRIX_MVP, // Shader location: matrix uniform: model-view-projection + MATRIX_VIEW, // Shader location: matrix uniform: view (camera transform) + MATRIX_PROJECTION, // Shader location: matrix uniform: projection + MATRIX_MODEL, // Shader location: matrix uniform: model (transform) + MATRIX_NORMAL, // Shader location: matrix uniform: normal + VECTOR_VIEW, // Shader location: vector uniform: view + COLOR_DIFFUSE, // Shader location: vector uniform: diffuse color + COLOR_SPECULAR, // Shader location: vector uniform: specular color + COLOR_AMBIENT, // Shader location: vector uniform: ambient color + MAP_ALBEDO, // Shader location: sampler2d texture: albedo (same as: SHADER_LOC_MAP_DIFFUSE) + MAP_METALNESS, // Shader location: sampler2d texture: metalness (same as: SHADER_LOC_MAP_SPECULAR) + MAP_NORMAL, // Shader location: sampler2d texture: normal + MAP_ROUGHNESS, // Shader location: sampler2d texture: roughness + MAP_OCCLUSION, // Shader location: sampler2d texture: occlusion + MAP_EMISSION, // Shader location: sampler2d texture: emission + MAP_HEIGHT, // Shader location: sampler2d texture: height + MAP_CUBEMAP, // Shader location: samplerCube texture: cubemap + MAP_IRRADIANCE, // Shader location: samplerCube texture: irradiance + MAP_PREFILTER, // Shader location: samplerCube texture: prefilter + MAP_BRDF, // Shader location: sampler2d texture: brdf + VERTEX_BONEIDS, // Shader location: vertex attribute: boneIds + VERTEX_BONEWEIGHTS, // Shader location: vertex attribute: boneWeights + BONE_MATRICES, // Shader location: array of matrices uniform: boneMatrices } // Shader uniform data type ShaderUniformDataType :: enum c.int { - FLOAT = 0, // Shader uniform type: float - VEC2, // Shader uniform type: vec2 (2 float) - VEC3, // Shader uniform type: vec3 (3 float) - VEC4, // Shader uniform type: vec4 (4 float) - INT, // Shader uniform type: int - IVEC2, // Shader uniform type: ivec2 (2 int) - IVEC3, // Shader uniform type: ivec3 (3 int) - IVEC4, // Shader uniform type: ivec4 (4 int) - SAMPLER2D, // Shader uniform type: sampler2d + FLOAT = 0, // Shader uniform type: float + VEC2, // Shader uniform type: vec2 (2 float) + VEC3, // Shader uniform type: vec3 (3 float) + VEC4, // Shader uniform type: vec4 (4 float) + INT, // Shader uniform type: int + IVEC2, // Shader uniform type: ivec2 (2 int) + IVEC3, // Shader uniform type: ivec3 (3 int) + IVEC4, // Shader uniform type: ivec4 (4 int) + SAMPLER2D, // Shader uniform type: sampler2d } // Pixel formats // NOTE: Support depends on OpenGL version and platform PixelFormat :: enum c.int { UNKNOWN = 0, - UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) - UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) - UNCOMPRESSED_R5G6B5, // 16 bpp - UNCOMPRESSED_R8G8B8, // 24 bpp - UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) - UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) - UNCOMPRESSED_R8G8B8A8, // 32 bpp - UNCOMPRESSED_R32, // 32 bpp (1 channel - float) - UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) - UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) - UNCOMPRESSED_R16, // 16 bpp (1 channel - float) - UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - float) - UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - float) - COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) - COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) - COMPRESSED_DXT3_RGBA, // 8 bpp - COMPRESSED_DXT5_RGBA, // 8 bpp - COMPRESSED_ETC1_RGB, // 4 bpp - COMPRESSED_ETC2_RGB, // 4 bpp - COMPRESSED_ETC2_EAC_RGBA, // 8 bpp - COMPRESSED_PVRT_RGB, // 4 bpp - COMPRESSED_PVRT_RGBA, // 4 bpp - COMPRESSED_ASTC_4x4_RGBA, // 8 bpp - COMPRESSED_ASTC_8x8_RGBA, // 2 bpp + UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha) + UNCOMPRESSED_GRAY_ALPHA, // 8*2 bpp (2 channels) + UNCOMPRESSED_R5G6B5, // 16 bpp + UNCOMPRESSED_R8G8B8, // 24 bpp + UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha) + UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha) + UNCOMPRESSED_R8G8B8A8, // 32 bpp + UNCOMPRESSED_R32, // 32 bpp (1 channel - float) + UNCOMPRESSED_R32G32B32, // 32*3 bpp (3 channels - float) + UNCOMPRESSED_R32G32B32A32, // 32*4 bpp (4 channels - float) + UNCOMPRESSED_R16, // 16 bpp (1 channel - float) + UNCOMPRESSED_R16G16B16, // 16*3 bpp (3 channels - float) + UNCOMPRESSED_R16G16B16A16, // 16*4 bpp (4 channels - float) + COMPRESSED_DXT1_RGB, // 4 bpp (no alpha) + COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha) + COMPRESSED_DXT3_RGBA, // 8 bpp + COMPRESSED_DXT5_RGBA, // 8 bpp + COMPRESSED_ETC1_RGB, // 4 bpp + COMPRESSED_ETC2_RGB, // 4 bpp + COMPRESSED_ETC2_EAC_RGBA, // 8 bpp + COMPRESSED_PVRT_RGB, // 4 bpp + COMPRESSED_PVRT_RGBA, // 4 bpp + COMPRESSED_ASTC_4x4_RGBA, // 8 bpp + COMPRESSED_ASTC_8x8_RGBA, // 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 TextureFilter :: enum c.int { - POINT = 0, // No filter, just pixel approximation - BILINEAR, // Linear filtering - TRILINEAR, // Trilinear filtering (linear with mipmaps) - ANISOTROPIC_4X, // Anisotropic filtering 4x - ANISOTROPIC_8X, // Anisotropic filtering 8x - ANISOTROPIC_16X, // Anisotropic filtering 16x + POINT = 0, // No filter, just pixel approximation + BILINEAR, // Linear filtering + TRILINEAR, // Trilinear filtering (linear with mipmaps) + ANISOTROPIC_4X, // Anisotropic filtering 4x + ANISOTROPIC_8X, // Anisotropic filtering 8x + ANISOTROPIC_16X, // Anisotropic filtering 16x } // Texture parameters: wrap mode TextureWrap :: enum c.int { - REPEAT = 0, // Repeats texture in tiled mode - CLAMP, // Clamps texture to edge pixel in tiled mode - MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode - MIRROR_CLAMP, // Mirrors and clamps to border the texture in tiled mode + REPEAT = 0, // Repeats texture in tiled mode + CLAMP, // Clamps texture to edge pixel in tiled mode + MIRROR_REPEAT, // Mirrors and repeats the texture in tiled mode + MIRROR_CLAMP, // Mirrors and clamps to border the texture in tiled mode } // Cubemap layouts CubemapLayout :: enum c.int { - AUTO_DETECT = 0, // Automatically detect layout type - LINE_VERTICAL, // Layout is defined by a vertical line with faces - LINE_HORIZONTAL, // Layout is defined by an horizontal line with faces - CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces - CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces + AUTO_DETECT = 0, // Automatically detect layout type + LINE_VERTICAL, // Layout is defined by a vertical line with faces + LINE_HORIZONTAL, // Layout is defined by an horizontal line with faces + CROSS_THREE_BY_FOUR, // Layout is defined by a 3x4 cross with cubemap faces + CROSS_FOUR_BY_THREE, // Layout is defined by a 4x3 cross with cubemap faces } // Font type, defines generation method FontType :: enum c.int { - DEFAULT = 0, // Default font generation, anti-aliased - BITMAP, // Bitmap font generation, no anti-aliasing - SDF, // SDF font generation, requires external shader + DEFAULT = 0, // Default font generation, anti-aliased + BITMAP, // Bitmap font generation, no anti-aliasing + SDF, // SDF font generation, requires external shader } // Color blending modes (pre-defined) BlendMode :: enum c.int { - ALPHA = 0, // Blend textures considering alpha (default) - ADDITIVE, // Blend textures adding colors - MULTIPLIED, // Blend textures multiplying colors - ADD_COLORS, // Blend textures adding colors (alternative) - SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) - ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha - CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) - CUSTOM_SEPARATE, // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) + ALPHA = 0, // Blend textures considering alpha (default) + ADDITIVE, // Blend textures adding colors + MULTIPLIED, // Blend textures multiplying colors + ADD_COLORS, // Blend textures adding colors (alternative) + SUBTRACT_COLORS, // Blend textures subtracting colors (alternative) + ALPHA_PREMULTIPLY, // Blend premultiplied textures considering alpha + CUSTOM, // Blend textures using custom src/dst factors (use rlSetBlendFactors()) + CUSTOM_SEPARATE, // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate()) } // Gestures // NOTE: It could be used as flags to enable only some gestures Gesture :: enum c.uint { - TAP = 0, // Tap gesture - DOUBLETAP = 1, // Double tap gesture - HOLD = 2, // Hold gesture - DRAG = 3, // Drag gesture - SWIPE_RIGHT = 4, // Swipe right gesture - SWIPE_LEFT = 5, // Swipe left gesture - SWIPE_UP = 6, // Swipe up gesture - SWIPE_DOWN = 7, // Swipe down gesture - PINCH_IN = 8, // Pinch in gesture - PINCH_OUT = 9, // Pinch out gesture + TAP = 0, // Tap gesture + DOUBLETAP = 1, // Double tap gesture + HOLD = 2, // Hold gesture + DRAG = 3, // Drag gesture + SWIPE_RIGHT = 4, // Swipe right gesture + SWIPE_LEFT = 5, // Swipe left gesture + SWIPE_UP = 6, // Swipe up gesture + SWIPE_DOWN = 7, // Swipe down gesture + PINCH_IN = 8, // Pinch in gesture + PINCH_OUT = 9, // Pinch out gesture } -Gestures :: distinct bit_set[Gesture;c.uint] +Gestures :: distinct bit_set[Gesture; c.uint] + +// Camera speed values +CAMERA_MOVE_SPEED :: 5.4 +CAMERA_ROTATION_SPEED :: 0.03 +CAMERA_PAN_SPEED :: 0.2 + +// Camera mouse movement sensitivity +CAMERA_MOUSE_MOVE_SENSITIVITY :: 0.003 + +// Camera orbital speed in CAMERA_ORBITAL mode +CAMERA_ORBITAL_SPEED :: 0.5 // Camera system modes CameraMode :: enum c.int { - CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) - FREE, // Camera free mode - ORBITAL, // Camera orbital, around target, zoom supported - FIRST_PERSON, // Camera first person - THIRD_PERSON, // Camera third person + CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing) + FREE, // Camera free mode + ORBITAL, // Camera orbital, around target, zoom supported + FIRST_PERSON, // Camera first person + THIRD_PERSON, // Camera third person } // Camera projection CameraProjection :: enum c.int { - PERSPECTIVE = 0, // Perspective projection - ORTHOGRAPHIC, // Orthographic projection + PERSPECTIVE = 0, // Perspective projection + ORTHOGRAPHIC, // Orthographic projection } // N-patch layout NPatchLayout :: enum c.int { - NINE_PATCH = 0, // Npatch layout: 3x3 tiles - THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles - THREE_PATCH_HORIZONTAL, // Npatch layout: 3x1 tiles + NINE_PATCH = 0, // Npatch layout: 3x3 tiles + THREE_PATCH_VERTICAL, // Npatch layout: 1x3 tiles + THREE_PATCH_HORIZONTAL, // Npatch layout: 3x1 tiles } // Callbacks to hook some internal functions // WARNING: This callbacks are intended for advanced users -TraceLogCallback :: #type proc "c" (logLevel: TraceLogLevel, text: cstring, args: ^c.va_list) // Logging: Redirect trace log messages -LoadFileDataCallback :: #type proc "c" (fileName: cstring, dataSize: ^c.int) -> [^]u8 // FileIO: Load binary data -SaveFileDataCallback :: #type proc "c" (fileName: cstring, data: rawptr, dataSize: c.int) -> bool // FileIO: Save binary data -LoadFileTextCallback :: #type proc "c" (fileName: cstring) -> [^]u8 // FileIO: Load text data -SaveFileTextCallback :: #type proc "c" (fileName: cstring, text: cstring) -> bool // FileIO: Save text data +TraceLogCallback :: #type proc "c" (logLevel: TraceLogLevel, text: cstring, args: ^c.va_list) // Logging: Redirect trace log messages +LoadFileDataCallback :: #type proc "c"(fileName: cstring, dataSize: ^c.int) -> [^]u8 // FileIO: Load binary data +SaveFileDataCallback :: #type proc "c" (fileName: cstring, data: rawptr, dataSize: c.int) -> bool // FileIO: Save binary data +LoadFileTextCallback :: #type proc "c" (fileName: cstring) -> [^]u8 // FileIO: Load text data +SaveFileTextCallback :: #type proc "c" (fileName: cstring, text: cstring) -> bool // FileIO: Save text data AudioCallback :: #type proc "c" (bufferData: rawptr, frames: c.uint) -@(default_calling_convention = "c") +@(default_calling_convention="c") foreign lib { //------------------------------------------------------------------------------------ // Global Variables Definition @@ -871,55 +885,55 @@ foreign lib { // Window-related functions - InitWindow :: proc(width, height: c.int, title: cstring) --- // Initialize window and OpenGL context - WindowShouldClose :: proc() -> bool --- // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) - CloseWindow :: proc() --- // Close window and unload OpenGL context - IsWindowReady :: proc() -> bool --- // Check if window has been initialized successfully - IsWindowFullscreen :: proc() -> bool --- // Check if window is currently fullscreen - IsWindowHidden :: proc() -> bool --- // Check if window is currently hidden - IsWindowMinimized :: proc() -> bool --- // Check if window is currently minimized - IsWindowMaximized :: proc() -> bool --- // Check if window is currently maximized - IsWindowFocused :: proc() -> bool --- // Check if window is currently focused - IsWindowResized :: proc() -> bool --- // Check if window has been resized last frame - IsWindowState :: proc(flags: ConfigFlags) -> bool --- // Check if one specific window flag is enabled - SetWindowState :: proc(flags: ConfigFlags) --- // Set window configuration state using flags - ClearWindowState :: proc(flags: ConfigFlags) --- // Clear window configuration state flags - ToggleFullscreen :: proc() --- // Toggle window state: fullscreen/windowed - ToggleBorderlessWindowed :: proc() --- // Toggle window state: borderless windowed - MaximizeWindow :: proc() --- // Set window state: maximized, if resizable - MinimizeWindow :: proc() --- // Set window state: minimized, if resizable - RestoreWindow :: proc() --- // Set window state: not minimized/maximized - SetWindowIcon :: proc(image: Image) --- // Set icon for window (single image, RGBA 32bit,) - SetWindowIcons :: proc(images: [^]Image, count: c.int) --- // Set icon for window (multiple images, RGBA 32bit,) - SetWindowTitle :: proc(title: cstring) --- // Set title for window - SetWindowPosition :: proc(x, y: c.int) --- // Set window position on screen - SetWindowMonitor :: proc(monitor: c.int) --- // Set monitor for the current window - SetWindowMinSize :: proc(width, height: c.int) --- // Set window minimum dimensions (for WINDOW_RESIZABLE) - SetWindowMaxSize :: proc(width, height: c.int) --- // Set window maximum dimensions (for WINDOW_RESIZABLE) - SetWindowSize :: proc(width, height: c.int) --- // Set window dimensions - SetWindowOpacity :: proc(opacity: f32) --- // Set window opacity [0.0f..1.0f] - SetWindowFocused :: proc() --- // Set window focused - GetWindowHandle :: proc() -> rawptr --- // Get native window handle - GetScreenWidth :: proc() -> c.int --- // Get current screen width - GetScreenHeight :: proc() -> c.int --- // Get current screen height - GetRenderWidth :: proc() -> c.int --- // Get current render width (it considers HiDPI) - GetRenderHeight :: proc() -> c.int --- // Get current render height (it considers HiDPI) - GetMonitorCount :: proc() -> c.int --- // Get number of connected monitors - GetCurrentMonitor :: proc() -> c.int --- // Get current monitor where window is placed - GetMonitorPosition :: proc(monitor: c.int) -> Vector2 --- // Get specified monitor position - GetMonitorWidth :: proc(monitor: c.int) -> c.int --- // Get specified monitor width (current video mode used by monitor) - GetMonitorHeight :: proc(monitor: c.int) -> c.int --- // Get specified monitor height (current video mode used by monitor) - GetMonitorPhysicalWidth :: proc(monitor: c.int) -> c.int --- // Get specified monitor physical width in millimetres - GetMonitorPhysicalHeight :: proc(monitor: c.int) -> c.int --- // Get specified monitor physical height in millimetres - GetMonitorRefreshRate :: proc(monitor: c.int) -> c.int --- // Get specified monitor refresh rate - GetWindowPosition :: proc() -> Vector2 --- // Get window position XY on monitor - GetWindowScaleDPI :: proc() -> Vector2 --- // Get window scale DPI factor - GetMonitorName :: proc(monitor: c.int) -> cstring --- // Get the human-readable, UTF-8 encoded name of the specified monitor - SetClipboardText :: proc(text: cstring) --- // Set clipboard text content - GetClipboardText :: proc() -> cstring --- // Get clipboard text content - GetClipboardImage :: proc() -> Image --- // Get clipboard image content - EnableEventWaiting :: proc() --- // Enable waiting for events on EndDrawing(), no automatic event polling - DisableEventWaiting :: proc() --- // Disable waiting for events on EndDrawing(), automatic events polling + InitWindow :: proc(width, height: c.int, title: cstring) --- // Initialize window and OpenGL context + WindowShouldClose :: proc() -> bool --- // Check if application should close (KEY_ESCAPE pressed or windows close icon clicked) + CloseWindow :: proc() --- // Close window and unload OpenGL context + IsWindowReady :: proc() -> bool --- // Check if window has been initialized successfully + IsWindowFullscreen :: proc() -> bool --- // Check if window is currently fullscreen + IsWindowHidden :: proc() -> bool --- // Check if window is currently hidden + IsWindowMinimized :: proc() -> bool --- // Check if window is currently minimized + IsWindowMaximized :: proc() -> bool --- // Check if window is currently maximized + IsWindowFocused :: proc() -> bool --- // Check if window is currently focused + IsWindowResized :: proc() -> bool --- // Check if window has been resized last frame + IsWindowState :: proc(flags: ConfigFlags) -> bool --- // Check if one specific window flag is enabled + SetWindowState :: proc(flags: ConfigFlags) --- // Set window configuration state using flags + ClearWindowState :: proc(flags: ConfigFlags) --- // Clear window configuration state flags + ToggleFullscreen :: proc() --- // Toggle window state: fullscreen/windowed + ToggleBorderlessWindowed :: proc() --- // Toggle window state: borderless windowed + MaximizeWindow :: proc() --- // Set window state: maximized, if resizable + MinimizeWindow :: proc() --- // Set window state: minimized, if resizable + RestoreWindow :: proc() --- // Set window state: not minimized/maximized + SetWindowIcon :: proc(image: Image) --- // Set icon for window (single image, RGBA 32bit,) + SetWindowIcons :: proc(images: [^]Image, count: c.int) --- // Set icon for window (multiple images, RGBA 32bit,) + SetWindowTitle :: proc(title: cstring) --- // Set title for window + SetWindowPosition :: proc(x, y: c.int) --- // Set window position on screen + SetWindowMonitor :: proc(monitor: c.int) --- // Set monitor for the current window + SetWindowMinSize :: proc(width, height: c.int) --- // Set window minimum dimensions (for WINDOW_RESIZABLE) + SetWindowMaxSize :: proc(width, height: c.int) --- // Set window maximum dimensions (for WINDOW_RESIZABLE) + SetWindowSize :: proc(width, height: c.int) --- // Set window dimensions + SetWindowOpacity :: proc(opacity: f32) --- // Set window opacity [0.0f..1.0f] + SetWindowFocused :: proc() --- // Set window focused + GetWindowHandle :: proc() -> rawptr --- // Get native window handle + GetScreenWidth :: proc() -> c.int --- // Get current screen width + GetScreenHeight :: proc() -> c.int --- // Get current screen height + GetRenderWidth :: proc() -> c.int --- // Get current render width (it considers HiDPI) + GetRenderHeight :: proc() -> c.int --- // Get current render height (it considers HiDPI) + GetMonitorCount :: proc() -> c.int --- // Get number of connected monitors + GetCurrentMonitor :: proc() -> c.int --- // Get current monitor where window is placed + GetMonitorPosition :: proc(monitor: c.int) -> Vector2 --- // Get specified monitor position + GetMonitorWidth :: proc(monitor: c.int) -> c.int --- // Get specified monitor width (current video mode used by monitor) + GetMonitorHeight :: proc(monitor: c.int) -> c.int --- // Get specified monitor height (current video mode used by monitor) + GetMonitorPhysicalWidth :: proc(monitor: c.int) -> c.int --- // Get specified monitor physical width in millimetres + GetMonitorPhysicalHeight :: proc(monitor: c.int) -> c.int --- // Get specified monitor physical height in millimetres + GetMonitorRefreshRate :: proc(monitor: c.int) -> c.int --- // Get specified monitor refresh rate + GetWindowPosition :: proc() -> Vector2 --- // Get window position XY on monitor + GetWindowScaleDPI :: proc() -> Vector2 --- // Get window scale DPI factor + GetMonitorName :: proc(monitor: c.int) -> cstring --- // Get the human-readable, UTF-8 encoded name of the specified monitor + SetClipboardText :: proc(text: cstring) --- // Set clipboard text content + GetClipboardText :: proc() -> cstring --- // Get clipboard text content + GetClipboardImage :: proc() -> Image --- // Get clipboard image content + EnableEventWaiting :: proc() --- // Enable waiting for events on EndDrawing(), no automatic event polling + DisableEventWaiting :: proc() --- // Disable waiting for events on EndDrawing(), automatic events polling GetGLProcAddress :: proc(proc_name: cstring) -> rawptr --- // Get GL proc address @@ -929,102 +943,102 @@ foreign lib { // 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 - SwapScreenBuffer :: proc() --- // Swap back buffer with front buffer (screen drawing) - PollInputEvents :: proc() --- // Register all input events - WaitTime :: proc(seconds: f64) --- // Wait for some time (halt program execution) + SwapScreenBuffer :: proc() --- // Swap back buffer with front buffer (screen drawing) + PollInputEvents :: proc() --- // Register all input events + WaitTime :: proc(seconds: f64) --- // Wait for some time (halt program execution) // Cursor-related functions - ShowCursor :: proc() --- // Shows cursor - HideCursor :: proc() --- // Hides cursor - IsCursorHidden :: proc() -> bool --- // Check if cursor is not visible - EnableCursor :: proc() --- // Enables cursor (unlock cursor) - DisableCursor :: proc() --- // Disables cursor (lock cursor) - IsCursorOnScreen :: proc() -> bool --- // Check if cursor is on the current screen. + ShowCursor :: proc() --- // Shows cursor + HideCursor :: proc() --- // Hides cursor + IsCursorHidden :: proc() -> bool --- // Check if cursor is not visible + EnableCursor :: proc() --- // Enables cursor (unlock cursor) + DisableCursor :: proc() --- // Disables cursor (lock cursor) + IsCursorOnScreen :: proc() -> bool --- // Check if cursor is on the current screen. // Drawing-related functions - ClearBackground :: proc(color: Color) --- // Set background color (framebuffer clear color) - BeginDrawing :: proc() --- // Setup canvas (framebuffer) to start drawing - EndDrawing :: proc() --- // End canvas drawing and swap buffers (double buffering) - BeginMode2D :: proc(camera: Camera2D) --- // Initialize 2D mode with custom camera (2D) - EndMode2D :: proc() --- // Ends 2D mode with custom camera - BeginMode3D :: proc(camera: Camera3D) --- // Initializes 3D mode with custom camera (3D) - EndMode3D :: proc() --- // Ends 3D mode and returns to default 2D orthographic mode - BeginTextureMode :: proc(target: RenderTexture2D) --- // Initializes render texture for drawing - EndTextureMode :: proc() --- // Ends drawing to render texture - BeginShaderMode :: proc(shader: Shader) --- // Begin custom shader drawing - EndShaderMode :: proc() --- // End custom shader drawing (use default shader) - BeginBlendMode :: proc(mode: BlendMode) --- // Begin blending mode (alpha, additive, multiplied) - EndBlendMode :: proc() --- // End blending mode (reset to default: alpha blending) - BeginScissorMode :: proc(x, y, width, height: c.int) --- // Begin scissor mode (define screen area for following drawing) - EndScissorMode :: proc() --- // End scissor mode - BeginVrStereoMode :: proc(config: VrStereoConfig) --- // Begin stereo rendering (requires VR simulator) - EndVrStereoMode :: proc() --- // End stereo rendering (requires VR simulator) + ClearBackground :: proc(color: Color) --- // Set background color (framebuffer clear color) + BeginDrawing :: proc() --- // Setup canvas (framebuffer) to start drawing + EndDrawing :: proc() --- // End canvas drawing and swap buffers (double buffering) + BeginMode2D :: proc(camera: Camera2D) --- // Initialize 2D mode with custom camera (2D) + EndMode2D :: proc() --- // Ends 2D mode with custom camera + BeginMode3D :: proc(camera: Camera3D) --- // Initializes 3D mode with custom camera (3D) + EndMode3D :: proc() --- // Ends 3D mode and returns to default 2D orthographic mode + BeginTextureMode :: proc(target: RenderTexture2D) --- // Initializes render texture for drawing + EndTextureMode :: proc() --- // Ends drawing to render texture + BeginShaderMode :: proc(shader: Shader) --- // Begin custom shader drawing + EndShaderMode :: proc() --- // End custom shader drawing (use default shader) + BeginBlendMode :: proc(mode: BlendMode) --- // Begin blending mode (alpha, additive, multiplied) + EndBlendMode :: proc() --- // End blending mode (reset to default: alpha blending) + BeginScissorMode :: proc(x, y, width, height: c.int) --- // Begin scissor mode (define screen area for following drawing) + EndScissorMode :: proc() --- // End scissor mode + BeginVrStereoMode :: proc(config: VrStereoConfig) --- // Begin stereo rendering (requires VR simulator) + EndVrStereoMode :: proc() --- // End stereo rendering (requires VR simulator) // VR stereo config functions for VR simulator - LoadVrStereoConfig :: proc(device: VrDeviceInfo) -> VrStereoConfig --- // Load VR stereo config for VR simulator device parameters - UnloadVrStereoConfig :: proc(config: VrStereoConfig) --- // Unload VR stereo config + LoadVrStereoConfig :: proc(device: VrDeviceInfo) -> VrStereoConfig --- // Load VR stereo config for VR simulator device parameters + UnloadVrStereoConfig :: proc(config: VrStereoConfig) --- // Unload VR stereo config // Shader management functions // NOTE: Shader functionality is not available on OpenGL 1.1 - LoadShader :: proc(vsFileName, fsFileName: cstring) -> Shader --- // Load shader from files and bind default locations - LoadShaderFromMemory :: proc(vsCode, fsCode: cstring) -> Shader --- // Load shader from code strings and bind default locations - IsShaderValid :: proc(shader: Shader) -> bool --- // Check if a shader is valid (loaded on GPU) - GetShaderLocation :: proc(shader: Shader, uniformName: cstring) -> c.int --- // Get shader uniform location - GetShaderLocationAttrib :: proc(shader: Shader, attribName: cstring) -> c.int --- // Get shader attribute location + LoadShader :: proc(vsFileName, fsFileName: cstring) -> Shader --- // Load shader from files and bind default locations + LoadShaderFromMemory :: proc(vsCode, fsCode: cstring) -> Shader --- // Load shader from code strings and bind default locations + IsShaderValid :: proc(shader: Shader) -> bool --- // Check if a shader is valid (loaded on GPU) + GetShaderLocation :: proc(shader: Shader, uniformName: cstring) -> c.int --- // Get shader uniform location + GetShaderLocationAttrib :: proc(shader: Shader, attribName: cstring) -> c.int --- // Get shader attribute location // We use #any_int here so we can pass ShaderLocationIndex - SetShaderValue :: proc(shader: Shader, #any_int locIndex: c.int, value: rawptr, uniformType: ShaderUniformDataType) --- // Set shader uniform value - SetShaderValueV :: proc(shader: Shader, #any_int locIndex: c.int, value: rawptr, uniformType: ShaderUniformDataType, count: c.int) --- // Set shader uniform value vector - SetShaderValueMatrix :: proc(shader: Shader, #any_int locIndex: c.int, mat: Matrix) --- // Set shader uniform value (matrix 4x4) - SetShaderValueTexture :: proc(shader: Shader, #any_int locIndex: c.int, texture: Texture2D) --- // Set shader uniform value for texture (sampler2d) - UnloadShader :: proc(shader: Shader) --- // Unload shader from GPU memory (VRAM) + SetShaderValue :: proc(shader: Shader, #any_int locIndex: c.int, value: rawptr, uniformType: ShaderUniformDataType) --- // Set shader uniform value + SetShaderValueV :: proc(shader: Shader, #any_int locIndex: c.int, value: rawptr, uniformType: ShaderUniformDataType, count: c.int) --- // Set shader uniform value vector + SetShaderValueMatrix :: proc(shader: Shader, #any_int locIndex: c.int, mat: Matrix) --- // Set shader uniform value (matrix 4x4) + SetShaderValueTexture :: proc(shader: Shader, #any_int locIndex: c.int, texture: Texture2D) --- // Set shader uniform value for texture (sampler2d) + UnloadShader :: proc(shader: Shader) --- // Unload shader from GPU memory (VRAM) // Screen-space-related functions - GetScreenToWorldRay :: proc(position: Vector2, camera: Camera) -> Ray --- // Get a ray trace from screen position (i.e mouse) - GetScreenToWorldRayEx :: proc(position: Vector2, camera: Camera, width: c.int, height: c.int) -> Ray --- // Get a ray trace from screen position (i.e mouse) in a viewport - GetWorldToScreen :: proc(position: Vector3, camera: Camera) -> Vector2 --- // Get the screen space position for a 3d world space position - GetWorldToScreenEx :: proc(position: Vector3, camera: Camera, width: c.int, height: c.int) -> Vector2 --- // Get size position for a 3d world space position - GetWorldToScreen2D :: proc(position: Vector2, camera: Camera2D) -> Vector2 --- // Get the screen space position for a 2d camera world space position - GetScreenToWorld2D :: proc(position: Vector2, camera: Camera2D) -> Vector2 --- // Get the world space position for a 2d camera screen space position - GetCameraMatrix :: proc(camera: Camera) -> Matrix --- // Get camera transform matrix (view matrix) - GetCameraMatrix2D :: proc(camera: Camera2D) -> Matrix --- // Get camera 2d transform matrix - + GetScreenToWorldRay :: proc(position: Vector2, camera: Camera) -> Ray --- // Get a ray trace from screen position (i.e mouse) + GetScreenToWorldRayEx :: proc(position: Vector2, camera: Camera, width: c.int, height: c.int) ->Ray --- // Get a ray trace from screen position (i.e mouse) in a viewport + GetWorldToScreen :: proc(position: Vector3, camera: Camera) -> Vector2 --- // Get the screen space position for a 3d world space position + GetWorldToScreenEx :: proc(position: Vector3, camera: Camera, width: c.int, height: c.int) -> Vector2 --- // Get size position for a 3d world space position + GetWorldToScreen2D :: proc(position: Vector2, camera: Camera2D) -> Vector2 --- // Get the screen space position for a 2d camera world space position + GetScreenToWorld2D :: proc(position: Vector2, camera: Camera2D) -> Vector2 --- // Get the world space position for a 2d camera screen space position + GetCameraMatrix :: proc(camera: Camera) -> Matrix --- // Get camera transform matrix (view matrix) + GetCameraMatrix2D :: proc(camera: Camera2D) -> Matrix --- // Get camera 2d transform matrix + // Timing-related functions SetTargetFPS :: proc(fps: c.int) --- // Set target FPS (maximum) - GetFPS :: proc() -> c.int --- // Returns current FPS - GetFrameTime :: proc() -> f32 --- // Returns time in seconds for last frame drawn (delta time) - GetTime :: proc() -> f64 --- // Returns elapsed time in seconds since InitWindow() + GetFPS :: proc() -> c.int --- // Returns current FPS + GetFrameTime :: proc() -> f32 --- // Returns time in seconds for last frame drawn (delta time) + GetTime :: proc() -> f64 --- // Returns elapsed time in seconds since InitWindow() // Random value generation functions - SetRandomSeed :: proc(seed: c.uint) --- // Set the seed for the random number generator - GetRandomValue :: proc(min, max: c.int) -> c.int --- // Get a random value between min and max (both included) - LoadRandomSequence :: proc(count: c.uint, min, max: c.int) -> [^]c.int --- // Load random values sequence, no values repeated - UnloadRandomSequence :: proc(sequence: [^]c.int) --- // Unload random values sequence + SetRandomSeed :: proc(seed: c.uint) --- // Set the seed for the random number generator + GetRandomValue :: proc(min, max: c.int) -> c.int --- // Get a random value between min and max (both included) + LoadRandomSequence :: proc(count: c.uint, min, max: c.int) -> [^]c.int --- // Load random values sequence, no values repeated + UnloadRandomSequence :: proc(sequence: [^]c.int) --- // Unload random values sequence // Misc. functions - TakeScreenshot :: proc(fileName: cstring) --- // Takes a screenshot of current screen (filename extension defines format) - SetConfigFlags :: proc(flags: ConfigFlags) --- // Setup init configuration flags (view FLAGS). NOTE: This function is expected to be called before window creation - OpenURL :: proc(url: cstring) --- // Open URL with default system browser (if available) + TakeScreenshot :: proc(fileName: cstring) --- // Takes a screenshot of current screen (filename extension defines format) + SetConfigFlags :: proc(flags: ConfigFlags) --- // Setup init configuration flags (view FLAGS). NOTE: This function is expected to be called before window creation + OpenURL :: proc(url: cstring) --- // Open URL with default system browser (if available) // NOTE: Following functions implemented in module [utils] //------------------------------------------------------------------ - TraceLog :: proc(logLevel: TraceLogLevel, text: cstring, #c_vararg args: ..any) --- // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR) - SetTraceLogLevel :: proc(logLevel: TraceLogLevel) --- // Set the current threshold (minimum) log level - MemAlloc :: proc(size: c.uint) -> rawptr --- // Internal memory allocator - MemRealloc :: proc(ptr: rawptr, size: c.uint) -> rawptr --- // Internal memory reallocator + TraceLog :: proc(logLevel: TraceLogLevel, text: cstring, #c_vararg args: ..any) --- // Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR) + SetTraceLogLevel :: proc(logLevel: TraceLogLevel) --- // Set the current threshold (minimum) log level + MemAlloc :: proc(size: c.uint) -> rawptr --- // Internal memory allocator + MemRealloc :: proc(ptr: rawptr, size: c.uint) -> rawptr --- // Internal memory reallocator // Set custom callbacks // WARNING: Callbacks setup is intended for advanced users - SetTraceLogCallback :: proc(callback: TraceLogCallback) --- // Set custom trace log + SetTraceLogCallback :: proc(callback: TraceLogCallback) --- // Set custom trace log SetLoadFileDataCallback :: proc(callback: LoadFileDataCallback) --- // Set custom file binary data loader SetSaveFileDataCallback :: proc(callback: SaveFileDataCallback) --- // Set custom file binary data saver SetLoadFileTextCallback :: proc(callback: LoadFileTextCallback) --- // Set custom file text data loader @@ -1032,60 +1046,60 @@ foreign lib { // Files management functions - LoadFileData :: proc(fileName: cstring, dataSize: ^c.int) -> [^]byte --- // Load file data as byte array (read) - UnloadFileData :: proc(data: [^]byte) --- // Unload file data allocated by LoadFileData() - SaveFileData :: proc(fileName: cstring, data: rawptr, dataSize: c.int) -> bool --- // Save data to file from byte array (write), returns true on success - ExportDataAsCode :: proc(data: rawptr, dataSize: c.int, fileName: cstring) -> bool --- // Export data to code (.h), returns true on success - LoadFileText :: proc(fileName: cstring) -> [^]byte --- // Load text data from file (read), returns a '\0' terminated string - UnloadFileText :: proc(text: [^]byte) --- // Unload file text data allocated by LoadFileText() - SaveFileText :: proc(fileName: cstring, text: [^]byte) -> bool --- // Save text data to file (write), string must be '\0' terminated, returns true on success + LoadFileData :: proc(fileName: cstring, dataSize: ^c.int) -> [^]byte --- // Load file data as byte array (read) + UnloadFileData :: proc(data: [^]byte) --- // Unload file data allocated by LoadFileData() + SaveFileData :: proc(fileName: cstring, data: rawptr, dataSize: c.int) -> bool --- // Save data to file from byte array (write), returns true on success + ExportDataAsCode :: proc(data: rawptr, dataSize: c.int, fileName: cstring) -> bool --- // Export data to code (.h), returns true on success + LoadFileText :: proc(fileName: cstring) -> [^]byte --- // Load text data from file (read), returns a '\0' terminated string + UnloadFileText :: proc(text: [^]byte) --- // Unload file text data allocated by LoadFileText() + SaveFileText :: proc(fileName: cstring, text: [^]byte) -> bool --- // Save text data to file (write), string must be '\0' terminated, returns true on success // File system functions - FileExists :: proc(fileName: cstring) -> bool --- // Check if file exists - DirectoryExists :: proc(dirPath: cstring) -> bool --- // Check if a directory path exists - IsFileExtension :: proc(fileName, ext: cstring) -> bool --- // Check file extension (including point: .png, .wav) - GetFileLength :: proc(fileName: cstring) -> c.int --- // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) - GetFileExtension :: proc(fileName: cstring) -> cstring --- // Get pointer to extension for a filename string (includes dot: '.png') - GetFileName :: proc(filePath: cstring) -> cstring --- // Get pointer to filename for a path string - GetFileNameWithoutExt :: proc(filePath: cstring) -> cstring --- // Get filename string without extension (uses static string) - GetDirectoryPath :: proc(filePath: cstring) -> cstring --- // Get full path for a given fileName with path (uses static string) - GetPrevDirectoryPath :: proc(dirPath: cstring) -> cstring --- // Get previous directory path for a given path (uses static string) - GetWorkingDirectory :: proc() -> cstring --- // Get current working directory (uses static string) - GetApplicationDirectory :: proc() -> cstring --- // Get the directory of the running application (uses static string) - MakeDirectory :: proc(dirPath: cstring) -> c.int --- // Create directories (including full path requested), returns 0 on success - ChangeDirectory :: proc(dir: cstring) -> bool --- // Change working directory, return true on success - IsPathFile :: proc(path: cstring) -> bool --- // Check if a given path is a file or a directory - IsFileNameValid :: proc(fileName: cstring) -> bool --- // Check if fileName is valid for the platform/OS - LoadDirectoryFiles :: proc(dirPath: cstring) -> FilePathList --- // Load directory filepaths - LoadDirectoryFilesEx :: proc(basePath: cstring, filter: cstring, scanSubdirs: bool) -> FilePathList --- // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result - UnloadDirectoryFiles :: proc(files: FilePathList) --- // Unload filepaths - IsFileDropped :: proc() -> bool --- // Check if a file has been dropped into window - LoadDroppedFiles :: proc() -> FilePathList --- // Load dropped filepaths - UnloadDroppedFiles :: proc(files: FilePathList) --- // Unload dropped filepaths - GetFileModTime :: proc(fileName: cstring) -> c.long --- // Get file modification time (last write time) + FileExists :: proc(fileName: cstring) -> bool --- // Check if file exists + DirectoryExists :: proc(dirPath: cstring) -> bool --- // Check if a directory path exists + IsFileExtension :: proc(fileName, ext: cstring) -> bool --- // Check file extension (including point: .png, .wav) + GetFileLength :: proc(fileName: cstring) -> c.int --- // Get file length in bytes (NOTE: GetFileSize() conflicts with windows.h) + GetFileExtension :: proc(fileName: cstring) -> cstring --- // Get pointer to extension for a filename string (includes dot: '.png') + GetFileName :: proc(filePath: cstring) -> cstring --- // Get pointer to filename for a path string + GetFileNameWithoutExt :: proc(filePath: cstring) -> cstring --- // Get filename string without extension (uses static string) + GetDirectoryPath :: proc(filePath: cstring) -> cstring --- // Get full path for a given fileName with path (uses static string) + GetPrevDirectoryPath :: proc(dirPath: cstring) -> cstring --- // Get previous directory path for a given path (uses static string) + GetWorkingDirectory :: proc() -> cstring --- // Get current working directory (uses static string) + GetApplicationDirectory :: proc() -> cstring --- // Get the directory of the running application (uses static string) + MakeDirectory :: proc(dirPath: cstring) -> c.int --- // Create directories (including full path requested), returns 0 on success + ChangeDirectory :: proc(dir: cstring) -> bool --- // Change working directory, return true on success + IsPathFile :: proc(path: cstring) -> bool --- // Check if a given path is a file or a directory + IsFileNameValid :: proc (fileName: cstring) -> bool --- // Check if fileName is valid for the platform/OS + LoadDirectoryFiles :: proc(dirPath: cstring) -> FilePathList --- // Load directory filepaths + LoadDirectoryFilesEx :: proc(basePath: cstring, filter: cstring, scanSubdirs: bool) -> FilePathList --- // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result + UnloadDirectoryFiles :: proc(files: FilePathList) --- // Unload filepaths + IsFileDropped :: proc() -> bool --- // Check if a file has been dropped into window + LoadDroppedFiles :: proc() -> FilePathList --- // Load dropped filepaths + UnloadDroppedFiles :: proc(files: FilePathList) --- // Unload dropped filepaths + GetFileModTime :: proc(fileName: cstring) -> c.long --- // Get file modification time (last write time) // Compression/Encoding functionality - CompressData :: proc(data: rawptr, dataSize: c.int, compDataSize: ^c.int) -> [^]byte --- // Compress data (DEFLATE algorithm), memory must be MemFree() - DecompressData :: proc(compData: rawptr, compDataSize: c.int, dataSize: ^c.int) -> [^]byte --- // Decompress data (DEFLATE algorithm), memory must be MemFree() - EncodeDataBase64 :: proc(data: rawptr, dataSize: c.int, outputSize: ^c.int) -> [^]byte --- // Encode data to Base64 string, memory must be MemFree() - DecodeDataBase64 :: proc(data: rawptr, outputSize: ^c.int) -> [^]byte --- // Decode Base64 string data, memory must be MemFree() - ComputeCRC32 :: proc(data: rawptr, dataSize: c.int) -> c.uint --- // Compute CRC32 hash code - ComputeMD5 :: proc(data: rawptr, dataSize: c.int) -> [^]c.uint --- // Compute MD5 hash code, returns static int[4] (16 bytes) - ComputeSHA1 :: proc(data: rawptr, dataSize: c.int) -> [^]c.uint --- // Compute SHA1 hash code, returns static int[5] (20 bytes) - + CompressData :: proc(data: rawptr, dataSize: c.int, compDataSize: ^c.int) -> [^]byte --- // Compress data (DEFLATE algorithm), memory must be MemFree() + DecompressData :: proc(compData: rawptr, compDataSize: c.int, dataSize: ^c.int) -> [^]byte --- // Decompress data (DEFLATE algorithm), memory must be MemFree() + EncodeDataBase64 :: proc(data: rawptr, dataSize: c.int, outputSize: ^c.int) -> [^]byte --- // Encode data to Base64 string, memory must be MemFree() + DecodeDataBase64 :: proc(data: rawptr, outputSize: ^c.int) -> [^]byte --- // Decode Base64 string data, memory must be MemFree() + ComputeCRC32 :: proc(data: rawptr, dataSize: c.int) -> c.uint --- // Compute CRC32 hash code + ComputeMD5 :: proc (data: rawptr, dataSize: c.int) -> [^]c.uint --- // Compute MD5 hash code, returns static int[4] (16 bytes) + ComputeSHA1 :: proc(data: rawptr, dataSize: c.int) -> [^]c.uint --- // Compute SHA1 hash code, returns static int[5] (20 bytes) + // Automation events functionality - LoadAutomationEventList :: proc(fileName: cstring) -> AutomationEventList --- // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS - UnloadAutomationEventList :: proc(list: AutomationEventList) --- // Unload automation events list from file - ExportAutomationEventList :: proc(list: AutomationEventList, fileName: cstring) -> bool --- // Export automation events list as text file - SetAutomationEventList :: proc(list: ^AutomationEventList) --- // Set automation event list to record to - SetAutomationEventBaseFrame :: proc(frame: c.int) --- // Set automation event internal base frame to start recording - StartAutomationEventRecording :: proc() --- // Start recording automation events (AutomationEventList must be set) - StopAutomationEventRecording :: proc() --- // Stop recording automation events - PlayAutomationEvent :: proc(event: AutomationEvent) --- // Play a recorded automation event + LoadAutomationEventList :: proc(fileName: cstring) -> AutomationEventList --- // Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS + UnloadAutomationEventList :: proc(list: AutomationEventList) --- // Unload automation events list from file + ExportAutomationEventList :: proc(list: AutomationEventList, fileName: cstring) -> bool --- // Export automation events list as text file + SetAutomationEventList :: proc(list: ^AutomationEventList) --- // Set automation event list to record to + SetAutomationEventBaseFrame :: proc(frame: c.int) --- // Set automation event internal base frame to start recording + StartAutomationEventRecording :: proc() --- // Start recording automation events (AutomationEventList must be set) + StopAutomationEventRecording :: proc() --- // Stop recording automation events + PlayAutomationEvent :: proc(event: AutomationEvent) --- // Play a recorded automation event //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) @@ -1093,76 +1107,93 @@ foreign lib { // Input-related functions: keyboard - IsKeyPressed :: proc(key: KeyboardKey) -> bool --- // Detect if a key has been pressed once + IsKeyPressed :: proc(key: KeyboardKey) -> bool --- // Detect if a key has been pressed once IsKeyPressedRepeat :: proc(key: KeyboardKey) -> bool --- // Check if a key has been pressed again - IsKeyDown :: proc(key: KeyboardKey) -> bool --- // Detect if a key is being pressed - IsKeyReleased :: proc(key: KeyboardKey) -> bool --- // Detect if a key has been released once - IsKeyUp :: proc(key: KeyboardKey) -> bool --- // Detect if a key is NOT being pressed - GetKeyPressed :: proc() -> KeyboardKey --- // Get key pressed (keycode), call it multiple times for keys queued - GetCharPressed :: proc() -> rune --- // Get char pressed (unicode), call it multiple times for chars queued - SetExitKey :: proc(key: KeyboardKey) --- // Set a custom key to exit program (default is ESC) + IsKeyDown :: proc(key: KeyboardKey) -> bool --- // Detect if a key is being pressed + IsKeyReleased :: proc(key: KeyboardKey) -> bool --- // Detect if a key has been released once + IsKeyUp :: proc(key: KeyboardKey) -> bool --- // Detect if a key is NOT being pressed + GetKeyPressed :: proc() -> KeyboardKey --- // Get key pressed (keycode), call it multiple times for keys queued + GetCharPressed :: proc() -> rune --- // Get char pressed (unicode), call it multiple times for chars queued + SetExitKey :: proc(key: KeyboardKey) --- // Set a custom key to exit program (default is ESC) // Input-related functions: gamepads - IsGamepadAvailable :: proc(gamepad: c.int) -> bool --- // Check if a gamepad is available - GetGamepadName :: proc(gamepad: c.int) -> cstring --- // Get gamepad internal name id - IsGamepadButtonPressed :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button has been pressed once - IsGamepadButtonDown :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button is being pressed - IsGamepadButtonReleased :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button has been released once - IsGamepadButtonUp :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button is NOT being pressed - GetGamepadButtonPressed :: proc() -> GamepadButton --- // Get the last gamepad button pressed - GetGamepadAxisCount :: proc(gamepad: c.int) -> c.int --- // Get gamepad axis count for a gamepad - GetGamepadAxisMovement :: proc(gamepad: c.int, axis: GamepadAxis) -> f32 --- // Get axis movement value for a gamepad axis - SetGamepadMappings :: proc(mappings: cstring) -> c.int --- // Set internal gamepad mappings (SDL_GameControllerDB) - SetGamepadVibration :: proc(gamepad: c.int, leftMotor: f32, rightMotor: f32, duration: f32) --- // Set gamepad vibration for both motors (duration in seconds) - + IsGamepadAvailable :: proc(gamepad: c.int) -> bool --- // Check if a gamepad is available + GetGamepadName :: proc(gamepad: c.int) -> cstring --- // Get gamepad internal name id + IsGamepadButtonPressed :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button has been pressed once + IsGamepadButtonDown :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button is being pressed + IsGamepadButtonReleased :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button has been released once + IsGamepadButtonUp :: proc(gamepad: c.int, button: GamepadButton) -> bool --- // Check if a gamepad button is NOT being pressed + GetGamepadButtonPressed :: proc() -> GamepadButton --- // Get the last gamepad button pressed + GetGamepadAxisCount :: proc(gamepad: c.int) -> c.int --- // Get gamepad axis count for a gamepad + GetGamepadAxisMovement :: proc(gamepad: c.int, axis: GamepadAxis) -> f32 --- // Get axis movement value for a gamepad axis + SetGamepadMappings :: proc(mappings: cstring) -> c.int --- // Set internal gamepad mappings (SDL_GameControllerDB) + SetGamepadVibration :: proc(gamepad: c.int, leftMotor: f32, rightMotor: f32, duration: f32) --- // Set gamepad vibration for both motors (duration in seconds) + // Input-related functions: mouse - IsMouseButtonPressed :: proc(button: MouseButton) -> bool --- // Detect if a mouse button has been pressed once - IsMouseButtonDown :: proc(button: MouseButton) -> bool --- // Detect if a mouse button is being pressed - IsMouseButtonReleased :: proc(button: MouseButton) -> bool --- // Detect if a mouse button has been released once - IsMouseButtonUp :: proc(button: MouseButton) -> bool --- - - GetMouseX :: proc() -> c.int --- // Returns mouse position X - GetMouseY :: proc() -> c.int --- // Returns mouse position Y - GetMousePosition :: proc() -> Vector2 --- // Returns mouse position XY - GetMouseDelta :: proc() -> Vector2 --- // Returns mouse delta XY - SetMousePosition :: proc(x, y: c.int) --- // Set mouse position XY - SetMouseOffset :: proc(offsetX, offsetY: c.int) --- // Set mouse offset - SetMouseScale :: proc(scaleX, scaleY: f32) --- // Set mouse scaling - GetMouseWheelMove :: proc() -> f32 --- // Returns mouse wheel movement Y - GetMouseWheelMoveV :: proc() -> Vector2 --- // Get mouse wheel movement for both X and Y - SetMouseCursor :: proc(cursor: MouseCursor) --- // Set mouse cursor + IsMouseButtonPressed :: proc(button: MouseButton) -> bool --- // Detect if a mouse button has been pressed once + IsMouseButtonDown :: proc(button: MouseButton) -> bool --- // Detect if a mouse button is being pressed + IsMouseButtonReleased :: proc(button: MouseButton) -> bool --- // Detect if a mouse button has been released once + IsMouseButtonUp :: proc(button: MouseButton) -> bool --- + + GetMouseX :: proc() -> c.int --- // Returns mouse position X + GetMouseY :: proc() -> c.int --- // Returns mouse position Y + GetMousePosition :: proc() -> Vector2 --- // Returns mouse position XY + GetMouseDelta :: proc() -> Vector2 --- // Returns mouse delta XY + SetMousePosition :: proc(x, y: c.int) --- // Set mouse position XY + SetMouseOffset :: proc(offsetX, offsetY: c.int) --- // Set mouse offset + SetMouseScale :: proc(scaleX, scaleY: f32) --- // Set mouse scaling + GetMouseWheelMove :: proc() -> f32 --- // Returns mouse wheel movement Y + GetMouseWheelMoveV :: proc() -> Vector2 --- // Get mouse wheel movement for both X and Y + SetMouseCursor :: proc(cursor: MouseCursor) --- // Set mouse cursor // Input-related functions: touch - GetTouchX :: proc() -> c.int --- // Returns touch position X for touch point 0 (relative to screen size) - GetTouchY :: proc() -> c.int --- // Returns touch position Y for touch point 0 (relative to screen size) - GetTouchPosition :: proc(index: c.int) -> Vector2 --- // Returns touch position XY for a touch point index (relative to screen size) - GetTouchPointId :: proc(index: c.int) -> c.int --- // Get touch point identifier for given index - GetTouchPointCount :: proc() -> c.int --- // Get number of touch points + GetTouchX :: proc() -> c.int --- // Returns touch position X for touch point 0 (relative to screen size) + GetTouchY :: proc() -> c.int --- // Returns touch position Y for touch point 0 (relative to screen size) + GetTouchPosition :: proc(index: c.int) -> Vector2 --- // Returns touch position XY for a touch point index (relative to screen size) + GetTouchPointId :: proc(index: c.int) -> c.int --- // Get touch point identifier for given index + GetTouchPointCount :: proc() -> c.int --- // Get number of touch points //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: rgestures) //------------------------------------------------------------------------------------ - SetGesturesEnabled :: proc(flags: Gestures) --- // Enable a set of gestures using flags + SetGesturesEnabled :: proc(flags: Gestures) --- // Enable a set of gestures using flags - GetGestureDetected :: proc() -> Gestures --- // Get latest detected gesture - GetGestureHoldDuration :: proc() -> f32 --- // Get gesture hold time in seconds - GetGestureDragVector :: proc() -> Vector2 --- // Get gesture drag vector - GetGestureDragAngle :: proc() -> f32 --- // Get gesture drag angle - GetGesturePinchVector :: proc() -> Vector2 --- // Get gesture pinch delta - GetGesturePinchAngle :: proc() -> f32 --- // Get gesture pinch angle + GetGestureDetected :: proc() -> Gestures --- // Get latest detected gesture + GetGestureHoldDuration :: proc() -> f32 --- // Get gesture hold time in seconds + GetGestureDragVector :: proc() -> Vector2 --- // Get gesture drag vector + GetGestureDragAngle :: proc() -> f32 --- // Get gesture drag angle + GetGesturePinchVector :: proc() -> Vector2 --- // Get gesture pinch delta + GetGesturePinchAngle :: proc() -> f32 --- // Get gesture pinch angle //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) //------------------------------------------------------------------------------------ - UpdateCamera :: proc(camera: ^Camera, mode: CameraMode) --- // Set camera mode (multiple camera modes available) + UpdateCamera :: proc(camera: ^Camera, mode: CameraMode) --- // Set camera mode (multiple camera modes available) UpdateCameraPro :: proc(camera: ^Camera, movement: Vector3, rotation: Vector3, zoom: f32) --- // Update camera movement/rotation + GetCameraForward :: proc(camera: ^Camera) -> Vector3 --- // returns the camera's forward vector (normalized) + GetCameraUp :: proc(camera: ^Camera) -> Vector3 --- // returns the camera's up vector (normalized) - might not be perpendicular to forward vector + GetCameraRight :: proc(camera: ^Camera) -> Vector3 --- // returns the camera's right vector (normalized) + + // Camera Movement/Rotation. Angle is provided in radians + + CameraMoveForward :: proc(camera: ^Camera, distance: f32, moveInWorldPlane: bool) --- // move the camera in its forward direction + CameraMoveUp :: proc(camera: ^Camera, distance: f32) --- // move camera in its up direction + CameraMoveRight :: proc(camera: ^Camera, distance: f32, moveInWorldPlane: bool) --- // move camera in it's current right direction + CameraMoveToTarget :: proc(camera: ^Camera, delta: f32) --- // moves the camera position closer/farther to/from the camera target + CameraYaw :: proc(camera: ^Camera, angle: f32, rotateAroundTarget: bool) --- // rotates the camera around its up vector (left and right) + CameraPitch :: proc(camera: ^Camera, angle: f32, lockView: bool, rotateAroundTarget: bool, rotateUp: bool) --- // rotates the camera around its right vector (up and down) + CameraRoll :: proc(camera: ^Camera, angle: f32) --- // rotates the camera around its forward vector (left and right) + + GetCameraViewMatrix :: proc(camera: ^Camera) -> Matrix --- // returns the camera view matrix + GetCameraProjectionMatrix :: proc(camera: ^Camera, aspect: f32) -> Matrix --- // returns the camera projection matrix + //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) //------------------------------------------------------------------------------------ @@ -1170,224 +1201,227 @@ foreign lib { // 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 - SetShapesTexture :: proc(texture: Texture2D, source: Rectangle) --- // Set texture and rectangle to be used on shapes drawing - GetShapesTexture :: proc() -> Texture2D --- // Get texture that is used for shapes drawing - GetShapesTextureRectangle :: proc() -> Rectangle --- // Get texture source rectangle that is used for shapes drawing - + SetShapesTexture :: proc(texture: Texture2D, source: Rectangle) --- // Set texture and rectangle to be used on shapes drawing + GetShapesTexture :: proc() -> Texture2D --- // Get texture that is used for shapes drawing + GetShapesTextureRectangle :: proc() -> Rectangle --- // Get texture source rectangle that is used for shapes drawing + // Basic shapes drawing functions - DrawPixel :: proc(posX, posY: c.int, color: Color) --- // Draw a pixel using geometry [Can be slow, use with care] - DrawPixelV :: proc(position: Vector2, color: Color) --- // Draw a pixel using geometry (Vector version) [Can be slow, use with care] - DrawLine :: proc(startPosX, startPosY, endPosX, endPosY: c.int, color: Color) --- // Draw a line - DrawLineV :: proc(startPos, endPos: Vector2, color: Color) --- // Draw a line (using gl lines) - DrawLineEx :: proc(startPos, endPos: Vector2, thick: f32, color: Color) --- // Draw a line (using triangles/quads) - DrawLineStrip :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw lines sequence (using gl lines) - DrawLineBezier :: proc(startPos, endPos: Vector2, thick: f32, color: Color) --- // Draw line segment cubic-bezier in-out interpolation - DrawCircle :: proc(centerX, centerY: c.int, radius: f32, color: Color) --- // Draw a color-filled circle - DrawCircleSector :: proc(center: Vector2, radius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw a piece of a circle - DrawCircleSectorLines :: proc(center: Vector2, radius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw circle sector outline - DrawCircleGradient :: proc(centerX, centerY: c.int, radius: f32, inner, outer: Color) --- // Draw a gradient-filled circle - DrawCircleV :: proc(center: Vector2, radius: f32, color: Color) --- // Draw a color-filled circle (Vector version) - DrawCircleLines :: proc(centerX, centerY: c.int, radius: f32, color: Color) --- // Draw circle outline - DrawCircleLinesV :: proc(center: Vector2, radius: f32, color: Color) --- // Draw circle outline (Vector version) - DrawEllipse :: proc(centerX, centerY: c.int, radiusH, radiusV: f32, color: Color) --- // Draw ellipse - DrawEllipseLines :: proc(centerX, centerY: c.int, radiusH, radiusV: f32, color: Color) --- // Draw ellipse outline - DrawRing :: proc(center: Vector2, innerRadius, outerRadius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw ring - DrawRingLines :: proc(center: Vector2, innerRadius, outerRadius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw ring outline - DrawRectangle :: proc(posX, posY: c.int, width, height: c.int, color: Color) --- // Draw a color-filled rectangle - DrawRectangleV :: proc(position: Vector2, size: Vector2, color: Color) --- // Draw a color-filled rectangle (Vector version) - DrawRectangleRec :: proc(rec: Rectangle, color: Color) --- // Draw a color-filled rectangle - DrawRectanglePro :: proc(rec: Rectangle, origin: Vector2, rotation: f32, color: Color) --- // Draw a color-filled rectangle with pro parameters - DrawRectangleGradientV :: proc(posX, posY: c.int, width, height: c.int, top, bottom: Color) --- // Draw a vertical-gradient-filled rectangle - DrawRectangleGradientH :: proc(posX, posY: c.int, width, height: c.int, left, right: Color) --- // Draw a horizontal-gradient-filled rectangle - DrawRectangleGradientEx :: proc(rec: Rectangle, topLeft, bottomLeft, topRight, bottomRight: Color) --- // Draw a gradient-filled rectangle with custom vertex colors - DrawRectangleLines :: proc(posX, posY: c.int, width, height: c.int, color: Color) --- // Draw rectangle outline - DrawRectangleLinesEx :: proc(rec: Rectangle, lineThick: f32, color: Color) --- // Draw rectangle outline with extended parameters - DrawRectangleRounded :: proc(rec: Rectangle, roundness: f32, segments: c.int, color: Color) --- // Draw rectangle with rounded edges - DrawRectangleRoundedLines :: proc(rec: Rectangle, roundness: f32, segments: c.int, lineThick: f32, color: Color) --- // Draw rectangle lines with rounded edges - DrawRectangleRoundedLinesEx :: proc(rec: Rectangle, roundness: f32, segments: c.int, lineThick: f32, color: Color) --- // Draw rectangle with rounded edges outline - DrawTriangle :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw a color-filled triangle (vertex in counter-clockwise order!) - DrawTriangleLines :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw triangle outline (vertex in counter-clockwise order!) - DrawTriangleFan :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle fan defined by points (first vertex is the center) - DrawTriangleStrip :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points - DrawPoly :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, color: Color) --- // Draw a regular polygon (Vector version) - DrawPolyLines :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, color: Color) --- // Draw a polygon outline of n sides - DrawPolyLinesEx :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, lineThick: f32, color: Color) --- // Draw a polygon outline of n sides with extended parameters + DrawPixel :: proc(posX, posY: c.int, color: Color) --- // Draw a pixel using geometry [Can be slow, use with care] + DrawPixelV :: proc(position: Vector2, color: Color) --- // Draw a pixel using geometry (Vector version) [Can be slow, use with care] + DrawLine :: proc(startPosX, startPosY, endPosX, endPosY: c.int, color: Color) --- // Draw a line + DrawLineV :: proc(startPos, endPos: Vector2, color: Color) --- // Draw a line (using gl lines) + DrawLineEx :: proc(startPos, endPos: Vector2, thick: f32, color: Color) --- // Draw a line (using triangles/quads) + DrawLineStrip :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw lines sequence (using gl lines) + DrawLineBezier :: proc(startPos, endPos: Vector2, thick: f32, color: Color) --- // Draw line segment cubic-bezier in-out interpolation + DrawCircle :: proc(centerX, centerY: c.int, radius: f32, color: Color) --- // Draw a color-filled circle + DrawCircleSector :: proc(center: Vector2, radius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw a piece of a circle + DrawCircleSectorLines :: proc(center: Vector2, radius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw circle sector outline + DrawCircleGradient :: proc(centerX, centerY: c.int, radius: f32, inner, outer: Color) --- // Draw a gradient-filled circle + DrawCircleV :: proc(center: Vector2, radius: f32, color: Color) --- // Draw a color-filled circle (Vector version) + DrawCircleLines :: proc(centerX, centerY: c.int, radius: f32, color: Color) --- // Draw circle outline + DrawCircleLinesV :: proc(center: Vector2, radius: f32, color: Color) --- // Draw circle outline (Vector version) + DrawEllipse :: proc(centerX, centerY: c.int, radiusH, radiusV: f32, color: Color) --- // Draw ellipse + DrawEllipseLines :: proc(centerX, centerY: c.int, radiusH, radiusV: f32, color: Color) --- // Draw ellipse outline + DrawRing :: proc(center: Vector2, innerRadius, outerRadius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw ring + DrawRingLines :: proc(center: Vector2, innerRadius, outerRadius: f32, startAngle, endAngle: f32, segments: c.int, color: Color) --- // Draw ring outline + DrawRectangle :: proc(posX, posY: c.int, width, height: c.int, color: Color) --- // Draw a color-filled rectangle + DrawRectangleV :: proc(position: Vector2, size: Vector2, color: Color) --- // Draw a color-filled rectangle (Vector version) + DrawRectangleRec :: proc(rec: Rectangle, color: Color) --- // Draw a color-filled rectangle + DrawRectanglePro :: proc(rec: Rectangle, origin: Vector2, rotation: f32, color: Color) --- // Draw a color-filled rectangle with pro parameters + DrawRectangleGradientV :: proc(posX, posY: c.int, width, height: c.int, top, bottom: Color) --- // Draw a vertical-gradient-filled rectangle + DrawRectangleGradientH :: proc(posX, posY: c.int, width, height: c.int, left, right: Color) --- // Draw a horizontal-gradient-filled rectangle + DrawRectangleGradientEx :: proc(rec: Rectangle, topLeft, bottomLeft, topRight, bottomRight: Color) --- // Draw a gradient-filled rectangle with custom vertex colors + DrawRectangleLines :: proc(posX, posY: c.int, width, height: c.int, color: Color) --- // Draw rectangle outline + DrawRectangleLinesEx :: proc(rec: Rectangle, lineThick: f32, color: Color) --- // Draw rectangle outline with extended parameters + DrawRectangleRounded :: proc(rec: Rectangle, roundness: f32, segments: c.int, color: Color) --- // Draw rectangle with rounded edges + DrawRectangleRoundedLines :: proc(rec: Rectangle, roundness: f32, segments: c.int, color: Color) --- // Draw rectangle lines with rounded edges + DrawRectangleRoundedLinesEx :: proc(rec: Rectangle, roundness: f32, segments: c.int, lineThick: f32, color: Color) --- // Draw rectangle with rounded edges outline + DrawTriangle :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw a color-filled triangle (vertex in counter-clockwise order!) + DrawTriangleLines :: proc(v1, v2, v3: Vector2, color: Color) --- // Draw triangle outline (vertex in counter-clockwise order!) + DrawTriangleFan :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle fan defined by points (first vertex is the center) + DrawTriangleStrip :: proc(points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points + DrawPoly :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, color: Color) --- // Draw a regular polygon (Vector version) + DrawPolyLines :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, color: Color) --- // Draw a polygon outline of n sides + DrawPolyLinesEx :: proc(center: Vector2, sides: c.int, radius: f32, rotation: f32, lineThick: f32, color: Color) --- // Draw a polygon outline of n sides with extended parameters // Splines drawing functions - DrawSplineLinear :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Linear, minimum 2 points - DrawSplineBasis :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: B-Spline, minimum 4 points - DrawSplineCatmullRom :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Catmull-Rom, minimum 4 points - DrawSplineBezierQuadratic :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] - DrawSplineBezierCubic :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] - DrawSplineSegmentLinear :: proc(p1, p2: Vector2, thick: f32, color: Color) --- // Draw spline segment: Linear, 2 points - DrawSplineSegmentBasis :: proc(p1, p2, p3, p4: Vector2, thick: f32, color: Color) --- // Draw spline segment: B-Spline, 4 points - DrawSplineSegmentCatmullRom :: proc(p1, p2, p3, p4: Vector2, thick: f32, color: Color) --- // Draw spline segment: Catmull-Rom, 4 points - DrawSplineSegmentBezierQuadratic :: proc(p1, c2, p3: Vector2, thick: f32, color: Color) --- // Draw spline segment: Quadratic Bezier, 2 points, 1 control point - DrawSplineSegmentBezierCubic :: proc(p1, c2, c3, p4: Vector2, thick: f32, color: Color) --- // Draw spline segment: Cubic Bezier, 2 points, 2 control points + DrawSplineLinear :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Linear, minimum 2 points + DrawSplineBasis :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: B-Spline, minimum 4 points + DrawSplineCatmullRom :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Catmull-Rom, minimum 4 points + DrawSplineBezierQuadratic :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] + DrawSplineBezierCubic :: proc(points: [^]Vector2, pointCount: c.int, thick: f32, color: Color) --- // Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] + DrawSplineSegmentLinear :: proc(p1, p2: Vector2, thick: f32, color: Color) --- // Draw spline segment: Linear, 2 points + DrawSplineSegmentBasis :: proc(p1, p2, p3, p4: Vector2, thick: f32, color: Color) --- // Draw spline segment: B-Spline, 4 points + DrawSplineSegmentCatmullRom :: proc(p1, p2, p3, p4: Vector2, thick: f32, color: Color) --- // Draw spline segment: Catmull-Rom, 4 points + DrawSplineSegmentBezierQuadratic :: proc(p1, c2, p3: Vector2, thick: f32, color: Color) --- // Draw spline segment: Quadratic Bezier, 2 points, 1 control point + DrawSplineSegmentBezierCubic :: proc(p1, c2, c3, p4: Vector2, thick: f32, 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] - GetSplinePointLinear :: proc(startPos, endPos: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Linear - GetSplinePointBasis :: proc(p1, p2, p3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: B-Spline - GetSplinePointCatmullRom :: proc(p1, p2, p3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Catmull-Rom - GetSplinePointBezierQuad :: proc(p1, c2, p3: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Quadratic Bezier - GetSplinePointBezierCubic :: proc(p1, c2, c3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Cubic Bezier - // Basic shapes collision detection functions - CheckCollisionRecs :: proc(rec1, rec2: Rectangle) -> bool --- // Check collision between two rectangles - CheckCollisionCircles :: proc(center1: Vector2, radius1: f32, center2: Vector2, radius2: f32) -> bool --- // Check collision between two circles - CheckCollisionCircleRec :: proc(center: Vector2, radius: f32, rec: Rectangle) -> bool --- // Check collision between circle and rectangle - CheckCollisionCircleLine :: proc(center: Vector2, radius: f32, p1, p2: Vector2) -> bool --- // Check if circle collides with a line created betweeen two points [p1] and [p2] - CheckCollisionPointRec :: proc(point: Vector2, rec: Rectangle) -> bool --- // Check if point is inside rectangle - CheckCollisionPointCircle :: proc(point, center: Vector2, radius: f32) -> bool --- // Check if point is inside circle - CheckCollisionPointTriangle :: proc(point: Vector2, p1, p2, p3: Vector2) -> bool --- // Check if point is inside a triangle - CheckCollisionPointLine :: proc(point: Vector2, p1, p2: Vector2, threshold: c.int) -> bool --- // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] - CheckCollisionPointPoly :: proc(point: Vector2, points: [^]Vector2, pointCount: c.int) -> bool --- // Check if point is within a polygon described by array of vertices - CheckCollisionLines :: proc(startPos1, endPos1, startPos2, endPos2: Vector2, collisionPoint: [^]Vector2) -> bool --- // Check the collision between two lines defined by two points each, returns collision point by reference - GetCollisionRec :: proc(rec1, rec2: Rectangle) -> Rectangle --- // Get collision rectangle for two rectangles collision + GetSplinePointLinear :: proc(startPos, endPos: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Linear + GetSplinePointBasis :: proc(p1, p2, p3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: B-Spline + GetSplinePointCatmullRom :: proc(p1, p2, p3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Catmull-Rom + GetSplinePointBezierQuad :: proc(p1, c2, p3: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Quadratic Bezier + GetSplinePointBezierCubic :: proc(p1, c2, c3, p4: Vector2, t: f32) -> Vector2 --- // Get (evaluate) spline point: Cubic Bezier + // Basic shapes collision detection functions + CheckCollisionRecs :: proc(rec1, rec2: Rectangle) -> bool --- // Check collision between two rectangles + CheckCollisionCircles :: proc(center1: Vector2, radius1: f32, center2: Vector2, radius2: f32) -> bool --- // Check collision between two circles + CheckCollisionCircleRec :: proc(center: Vector2, radius: f32, rec: Rectangle) -> bool --- // Check collision between circle and rectangle + CheckCollisionCircleLine :: proc(center: Vector2, radius: f32, p1, p2: Vector2) -> bool --- // Check if circle collides with a line created betweeen two points [p1] and [p2] + CheckCollisionPointRec :: proc(point: Vector2, rec: Rectangle) -> bool --- // Check if point is inside rectangle + CheckCollisionPointCircle :: proc(point, center: Vector2, radius: f32) -> bool --- // Check if point is inside circle + CheckCollisionPointTriangle :: proc(point: Vector2, p1, p2, p3: Vector2) -> bool --- // Check if point is inside a triangle + CheckCollisionPointLine :: proc(point: Vector2, p1, p2: Vector2, threshold: c.int) -> bool --- // Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] + CheckCollisionPointPoly :: proc(point: Vector2, points: [^]Vector2, pointCount: c.int) -> bool --- // Check if point is within a polygon described by array of vertices + CheckCollisionLines :: proc(startPos1, endPos1, startPos2, endPos2: Vector2, collisionPoint: [^]Vector2) -> bool --- // Check the collision between two lines defined by two points each, returns collision point by reference + GetCollisionRec :: proc(rec1, rec2: Rectangle) -> Rectangle --- // Get collision rectangle for two rectangles collision + // Image loading functions // NOTE: These functions do not require GPU access - LoadImage :: proc(fileName: cstring) -> Image --- // Load image from file into CPU memory (RAM) - LoadImageRaw :: proc(fileName: cstring, width, height: c.int, format: PixelFormat, headerSize: c.int) -> Image --- // Load image from RAW file data - LoadImageAnim :: proc(fileName: cstring, frames: ^c.int) -> Image --- // Load image sequence from file (frames appended to image.data) - LoadImageAnimFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int, frames: ^c.int) -> Image --- // Load image sequence from memory buffer - LoadImageFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int) -> Image --- // Load image from memory buffer, fileType refers to extension: i.e. '.png' - LoadImageFromTexture :: proc(texture: Texture2D) -> Image --- // Load image from GPU texture data - LoadImageFromScreen :: proc() -> Image --- // Load image from screen buffer and (screenshot) - IsImageValid :: proc(image: Image) -> bool --- // Check if an image is ready - UnloadImage :: proc(image: Image) --- // Unload image from CPU memory (RAM) - ExportImage :: proc(image: Image, fileName: cstring) -> bool --- // Export image data to file, returns true on success - ExportImageToMemory :: proc(image: Image, fileType: cstring, fileSize: ^c.int) -> rawptr --- // Export image to memory buffer - ExportImageAsCode :: proc(image: Image, fileName: cstring) -> bool --- // Export image as code file defining an array of bytes, returns true on success + LoadImage :: proc(fileName: cstring) -> Image --- // Load image from file into CPU memory (RAM) + LoadImageRaw :: proc(fileName: cstring, width, height: c.int, format: PixelFormat, headerSize: c.int) -> Image --- // Load image from RAW file data + LoadImageAnim :: proc(fileName: cstring, frames: ^c.int) -> Image --- // Load image sequence from file (frames appended to image.data) + LoadImageAnimFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int, frames: ^c.int) -> Image --- // Load image sequence from memory buffer + LoadImageFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int) -> Image --- // Load image from memory buffer, fileType refers to extension: i.e. '.png' + LoadImageFromTexture :: proc(texture: Texture2D) -> Image --- // Load image from GPU texture data + LoadImageFromScreen :: proc() -> Image --- // Load image from screen buffer and (screenshot) + IsImageValid :: proc(image: Image) -> bool --- // Check if an image is ready + UnloadImage :: proc(image: Image) --- // Unload image from CPU memory (RAM) + ExportImage :: proc(image: Image, fileName: cstring) -> bool --- // Export image data to file, returns true on success + ExportImageToMemory :: proc(image: Image, fileType: cstring, fileSize: ^c.int) -> rawptr --- // Export image to memory buffer + ExportImageAsCode :: proc(image: Image, fileName: cstring) -> bool --- // Export image as code file defining an array of bytes, returns true on success // Image generation functions - GenImageColor :: proc(width, height: c.int, color: Color) -> Image --- // Generate image: plain color - GenImageGradientLinear :: proc(width, height, direction: c.int, start, end: Color) -> Image --- // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient - GenImageGradientRadial :: proc(width, height: c.int, density: f32, inner, outer: Color) -> Image --- // Generate image: radial gradient - GenImageGradientSquare :: proc(width, height: c.int, density: f32, inner, outer: Color) -> Image --- // Generate image: square gradient - GenImageChecked :: proc(width, height: c.int, checksX, checksY: c.int, col1, col2: Color) -> Image --- // Generate image: checked - GenImageWhiteNoise :: proc(width, height: c.int, factor: f32) -> Image --- // Generate image: white noise - GenImagePerlinNoise :: proc(width, height: c.int, offsetX, offsetY: c.int, scale: f32) -> Image --- // Generate image: perlin noise - GenImageCellular :: proc(width, height: c.int, tileSize: c.int) -> Image --- // Generate image: cellular algorithm, bigger tileSize means bigger cells - GenImageText :: proc(width, height: c.int, text: cstring) -> Image --- // Generate image: grayscale image from text data + GenImageColor :: proc(width, height: c.int, color: Color) -> Image --- // Generate image: plain color + GenImageGradientLinear :: proc(width, height, direction: c.int, start, end: Color) -> Image --- // Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient + GenImageGradientRadial :: proc(width, height: c.int, density: f32, inner, outer: Color) -> Image --- // Generate image: radial gradient + GenImageGradientSquare :: proc(width, height: c.int, density: f32, inner, outer: Color) -> Image --- // Generate image: square gradient + GenImageChecked :: proc(width, height: c.int, checksX, checksY: c.int, col1, col2: Color) -> Image --- // Generate image: checked + GenImageWhiteNoise :: proc(width, height: c.int, factor: f32) -> Image --- // Generate image: white noise + GenImagePerlinNoise :: proc(width, height: c.int, offsetX, offsetY: c.int, scale: f32) -> Image --- // Generate image: perlin noise + GenImageCellular :: proc(width, height: c.int, tileSize: c.int) -> Image --- // Generate image: cellular algorithm, bigger tileSize means bigger cells + GenImageText :: proc(width, height: c.int, text: cstring) -> Image --- // Generate image: grayscale image from text data // Image manipulation functions - ImageCopy :: proc(image: Image) -> Image --- // Create an image duplicate (useful for transformations) - ImageFromImage :: proc(image: Image, rec: Rectangle) -> Image --- // Create an image from another image piece - ImageFromChannel :: proc(image: Image, selectedChannel: c.int) -> Image --- // Create an image from a selected channel of another image (GRAYSCALE) - ImageText :: proc(text: cstring, fontSize: c.int, color: Color) -> Image --- // Create an image from text (default font) - ImageTextEx :: proc(font: Font, text: cstring, fontSize: f32, spacing: f32, tint: Color) -> Image --- // Create an image from text (custom sprite font) - ImageFormat :: proc(image: ^Image, newFormat: PixelFormat) --- // Convert image data to desired format - ImageToPOT :: proc(image: ^Image, fill: Color) --- // Convert image to POT (power-of-two) - ImageCrop :: proc(image: ^Image, crop: Rectangle) --- // Crop an image to a defined rectangle - ImageAlphaCrop :: proc(image: ^Image, threshold: f32) --- // Crop image depending on alpha value - ImageAlphaClear :: proc(image: ^Image, color: Color, threshold: f32) --- // Clear alpha channel to desired color - ImageAlphaMask :: proc(image: ^Image, alphaMask: Image) --- // Apply alpha mask to image - ImageAlphaPremultiply :: proc(image: ^Image) --- // Premultiply alpha channel - ImageBlurGaussian :: proc(image: ^Image, blurSize: c.int) --- // Apply Gaussian blur using a box blur approximation - ImageKernelConvolution :: proc(image: ^Image, kernel: [^]f32, kernelSize: c.int) --- // Apply custom square convolution kernel to image - ImageResize :: proc(image: ^Image, newWidth, newHeight: c.int) --- // Resize image (Bicubic scaling algorithm) - ImageResizeNN :: proc(image: ^Image, newWidth, newHeight: c.int) --- // Resize image (Nearest-Neighbor scaling algorithm) - ImageResizeCanvas :: proc(image: ^Image, newWidth, newHeight: c.int, offsetX, offsetY: c.int, fill: Color) --- // Resize canvas and fill with color - ImageMipmaps :: proc(image: ^Image) --- // Compute all mipmap levels for a provided image - ImageDither :: proc(image: ^Image, rBpp, gBpp, bBpp, aBpp: c.int) --- // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) - ImageFlipVertical :: proc(image: ^Image) --- // Flip image vertically - ImageFlipHorizontal :: proc(image: ^Image) --- // Flip image horizontally - ImageRotate :: proc(image: ^Image, degrees: c.int) --- // Rotate image by input angle in degrees( -359 to 359) - ImageRotateCW :: proc(image: ^Image) --- // Rotate image clockwise 90deg - ImageRotateCCW :: proc(image: ^Image) --- // Rotate image counter-clockwise 90deg - ImageColorTint :: proc(image: ^Image, color: Color) --- // Modify image color: tint - ImageColorInvert :: proc(image: ^Image) --- // Modify image color: invert - ImageColorGrayscale :: proc(image: ^Image) --- // Modify image color: grayscale - ImageColorContrast :: proc(image: ^Image, contrast: f32) --- // Modify image color: contrast (-100 to 100) - ImageColorBrightness :: proc(image: ^Image, brightness: c.int) --- // Modify image color: brightness (-255 to 255) - ImageColorReplace :: proc(image: ^Image, color, replace: Color) --- // Modify image color: replace color - LoadImageColors :: proc(image: Image) -> [^]Color --- // Load color data from image as a Color array (RGBA - 32bit) - LoadImagePalette :: proc(image: Image, maxPaletteSize: c.int, colorCount: ^c.int) -> [^]Color --- // Load colors palette from image as a Color array (RGBA - 32bit) - UnloadImageColors :: proc(colors: [^]Color) --- // Unload color data loaded with LoadImageColors() - UnloadImagePalette :: proc(colors: [^]Color) --- // Unload colors palette loaded with LoadImagePalette() - GetImageAlphaBorder :: proc(image: Image, threshold: f32) -> Rectangle --- // Get image alpha border rectangle - GetImageColor :: proc(image: Image, x, y: c.int) -> Color --- // Get image pixel color at (x, y) position + ImageCopy :: proc(image: Image) -> Image --- // Create an image duplicate (useful for transformations) + ImageFromImage :: proc(image: Image, rec: Rectangle) -> Image --- // Create an image from another image piece + ImageFromChannel :: proc(image: Image, selectedChannel: c.int) -> Image --- // Create an image from a selected channel of another image (GRAYSCALE) + ImageText :: proc(text: cstring, fontSize: c.int, color: Color) -> Image --- // Create an image from text (default font) + ImageTextEx :: proc(font: Font, text: cstring, fontSize: f32, spacing: f32, tint: Color) -> Image --- // Create an image from text (custom sprite font) + ImageFormat :: proc(image: ^Image, newFormat: PixelFormat) --- // Convert image data to desired format + ImageToPOT :: proc(image: ^Image, fill: Color) --- // Convert image to POT (power-of-two) + ImageCrop :: proc(image: ^Image, crop: Rectangle) --- // Crop an image to a defined rectangle + ImageAlphaCrop :: proc(image: ^Image, threshold: f32) --- // Crop image depending on alpha value + ImageAlphaClear :: proc(image: ^Image, color: Color, threshold: f32) --- // Clear alpha channel to desired color + ImageAlphaMask :: proc(image: ^Image, alphaMask: Image) --- // Apply alpha mask to image + ImageAlphaPremultiply :: proc(image: ^Image) --- // Premultiply alpha channel + ImageBlurGaussian :: proc(image: ^Image, blurSize: c.int) --- // Apply Gaussian blur using a box blur approximation + ImageKernelConvolution :: proc(image: ^Image, kernel: [^]f32, kernelSize: c.int) --- // Apply custom square convolution kernel to image + ImageResize :: proc(image: ^Image, newWidth, newHeight: c.int) --- // Resize image (Bicubic scaling algorithm) + ImageResizeNN :: proc(image: ^Image, newWidth, newHeight: c.int) --- // Resize image (Nearest-Neighbor scaling algorithm) + ImageResizeCanvas :: proc(image: ^Image, newWidth, newHeight: c.int, offsetX, offsetY: c.int, fill: Color) --- // Resize canvas and fill with color + ImageMipmaps :: proc(image: ^Image) --- // Compute all mipmap levels for a provided image + ImageDither :: proc(image: ^Image, rBpp, gBpp, bBpp, aBpp: c.int) --- // Dither image data to 16bpp or lower (Floyd-Steinberg dithering) + ImageFlipVertical :: proc(image: ^Image) --- // Flip image vertically + ImageFlipHorizontal :: proc(image: ^Image) --- // Flip image horizontally + ImageRotate :: proc(image: ^Image, degrees: c.int) --- // Rotate image by input angle in degrees( -359 to 359) + ImageRotateCW :: proc(image: ^Image) --- // Rotate image clockwise 90deg + ImageRotateCCW :: proc(image: ^Image) --- // Rotate image counter-clockwise 90deg + ImageColorTint :: proc(image: ^Image, color: Color) --- // Modify image color: tint + ImageColorInvert :: proc(image: ^Image) --- // Modify image color: invert + ImageColorGrayscale :: proc(image: ^Image) --- // Modify image color: grayscale + ImageColorContrast :: proc(image: ^Image, contrast: f32) --- // Modify image color: contrast (-100 to 100) + ImageColorBrightness :: proc(image: ^Image, brightness: c.int) --- // Modify image color: brightness (-255 to 255) + ImageColorReplace :: proc(image: ^Image, color, replace: Color) --- // Modify image color: replace color + LoadImageColors :: proc(image: Image) -> [^]Color --- // Load color data from image as a Color array (RGBA - 32bit) + LoadImagePalette :: proc(image: Image, maxPaletteSize: c.int, colorCount: ^c.int) -> [^]Color --- // Load colors palette from image as a Color array (RGBA - 32bit) + UnloadImageColors :: proc(colors: [^]Color) --- // Unload color data loaded with LoadImageColors() + UnloadImagePalette :: proc(colors: [^]Color) --- // Unload colors palette loaded with LoadImagePalette() + GetImageAlphaBorder :: proc(image: Image, threshold: f32) -> Rectangle --- // Get image alpha border rectangle + GetImageColor :: proc(image: Image, x, y: c.int) -> Color --- // Get image pixel color at (x, y) position // Image drawing functions // NOTE: Image software-rendering functions (CPU) - ImageClearBackground :: proc(dst: ^Image, color: Color) --- // Clear image background with given color - ImageDrawPixel :: proc(dst: ^Image, posX, posY: c.int, color: Color) --- // Draw pixel within an image - ImageDrawPixelV :: proc(dst: ^Image, position: Vector2, color: Color) --- // Draw pixel within an image (Vector version) - ImageDrawLine :: proc(dst: ^Image, startPosX, startPosY, endPosX, endPosY: c.int, color: Color) --- // Draw line within an image - ImageDrawLineV :: proc(dst: ^Image, start, end: Vector2, color: Color) --- // Draw line within an image (Vector version) - ImageDrawLineEx :: proc(dst: ^Image, start, end: Vector2, thick: c.int, color: Color) --- // Draw a line defining thickness within an image - ImageDrawCircle :: proc(dst: ^Image, centerX, centerY: c.int, radius: c.int, color: Color) --- // Draw a filled circle within an image - ImageDrawCircleV :: proc(dst: ^Image, center: Vector2, radius: c.int, color: Color) --- // Draw a filled circle within an image (Vector version) - ImageDrawCircleLines :: proc(dst: ^Image, centerX, centerY: c.int, radius: c.int, color: Color) --- // Draw circle outline within an image - ImageDrawCircleLinesV :: proc(dst: ^Image, center: Vector2, radius: c.int, color: Color) --- // Draw circle outline within an image (Vector version) - ImageDrawRectangle :: proc(dst: ^Image, posX, posY: c.int, width, height: c.int, color: Color) --- // Draw rectangle within an image - ImageDrawRectangleV :: proc(dst: ^Image, position, size: Vector2, color: Color) --- // Draw rectangle within an image (Vector version) - ImageDrawRectangleRec :: proc(dst: ^Image, rec: Rectangle, color: Color) --- // Draw rectangle within an image - ImageDrawRectangleLines :: proc(dst: ^Image, rec: Rectangle, thick: c.int, color: Color) --- // Draw rectangle lines within an image - ImageDrawTriangle :: proc(dst: ^Image, v1, v2, v3: Vector2, color: Color) --- // Draw triangle within an image - ImageDrawTriangleEx :: proc(dst: ^Image, v1, v2, v3: Vector2, c1, c2, c3: Color) --- // Draw triangle with interpolated colors within an image - ImageDrawTriangleLines :: proc(dst: ^Image, v1, v2, v3: Vector2, color: Color) --- // Draw triangle outline within an image - ImageDrawTriangleFan :: proc(dst: ^Image, points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle fan defined by points within an image (first vertex is the center) - ImageDrawTriangleStrip :: proc(dst: ^Image, points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points within an image - ImageDraw :: proc(dst: ^Image, src: Image, srcRec, dstRec: Rectangle, tint: Color) --- // Draw a source image within a destination image (tint applied to source) - ImageDrawText :: proc(dst: ^Image, text: cstring, posX, posY: c.int, fontSize: c.int, color: Color) --- // Draw text (using default font) within an image (destination) - ImageDrawTextEx :: proc(dst: ^Image, font: Font, text: cstring, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw text (custom sprite font) within an image (destination) + ImageClearBackground :: proc(dst: ^Image, color: Color) --- // Clear image background with given color + ImageDrawPixel :: proc(dst: ^Image, posX, posY: c.int, color: Color) --- // Draw pixel within an image + ImageDrawPixelV :: proc(dst: ^Image, position: Vector2, color: Color) --- // Draw pixel within an image (Vector version) + ImageDrawLine :: proc(dst: ^Image, startPosX, startPosY, endPosX, endPosY: c.int, color: Color) --- // Draw line within an image + ImageDrawLineV :: proc(dst: ^Image, start, end: Vector2, color: Color) --- // Draw line within an image (Vector version) + ImageDrawLineEx :: proc(dst: ^Image, start, end: Vector2, thick: c.int, color: Color) --- // Draw a line defining thickness within an image + ImageDrawCircle :: proc(dst: ^Image, centerX, centerY: c.int, radius: c.int, color: Color) --- // Draw a filled circle within an image + ImageDrawCircleV :: proc(dst: ^Image, center: Vector2, radius: c.int, color: Color) --- // Draw a filled circle within an image (Vector version) + ImageDrawCircleLines :: proc(dst: ^Image, centerX, centerY: c.int, radius: c.int, color: Color) --- // Draw circle outline within an image + ImageDrawCircleLinesV :: proc(dst: ^Image, center: Vector2, radius: c.int, color: Color) --- // Draw circle outline within an image (Vector version) + ImageDrawRectangle :: proc(dst: ^Image, posX, posY: c.int, width, height: c.int, color: Color) --- // Draw rectangle within an image + ImageDrawRectangleV :: proc(dst: ^Image, position, size: Vector2, color: Color) --- // Draw rectangle within an image (Vector version) + ImageDrawRectangleRec :: proc(dst: ^Image, rec: Rectangle, color: Color) --- // Draw rectangle within an image + ImageDrawRectangleLines :: proc(dst: ^Image, rec: Rectangle, thick: c.int, color: Color) --- // Draw rectangle lines within an image + ImageDrawTriangle :: proc(dst: ^Image, v1, v2, v3: Vector2, color: Color) --- // Draw triangle within an image + ImageDrawTriangleEx :: proc(dst: ^Image, v1, v2, v3: Vector2, c1, c2, c3: Color) --- // Draw triangle with interpolated colors within an image + ImageDrawTriangleLines :: proc(dst: ^Image, v1, v2, v3: Vector2, color: Color) --- // Draw triangle outline within an image + ImageDrawTriangleFan :: proc(dst: ^Image, points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle fan defined by points within an image (first vertex is the center) + ImageDrawTriangleStrip :: proc(dst: ^Image, points: [^]Vector2, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points within an image + ImageDraw :: proc(dst: ^Image, src: Image, srcRec, dstRec: Rectangle, tint: Color) --- // Draw a source image within a destination image (tint applied to source) + ImageDrawText :: proc(dst: ^Image, text: cstring, posX, posY: c.int, fontSize: c.int, color: Color) --- // Draw text (using default font) within an image (destination) + ImageDrawTextEx :: proc(dst: ^Image, font: Font, text: cstring, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw text (custom sprite font) within an image (destination) // Texture loading functions // NOTE: These functions require GPU access - LoadTexture :: proc(fileName: cstring) -> Texture2D --- // Load texture from file into GPU memory (VRAM) - LoadTextureFromImage :: proc(image: Image) -> Texture2D --- // Load texture from image data - LoadTextureCubemap :: proc(image: Image, layout: CubemapLayout) -> TextureCubemap --- // Load cubemap from image, multiple image cubemap layouts supported - LoadRenderTexture :: proc(width, height: c.int) -> RenderTexture2D --- // Load texture for rendering (framebuffer) - IsTextureValid :: proc(texture: Texture2D) -> bool --- // Check if a texture is valid - UnloadTexture :: proc(texture: Texture2D) --- // Unload texture from GPU memory (VRAM) - IsRenderTextureValid :: proc(target: RenderTexture2D) -> bool --- // Check if a render texture is valid - UnloadRenderTexture :: proc(target: RenderTexture2D) --- // Unload render texture from GPU memory (VRAM) - UpdateTexture :: proc(texture: Texture2D, pixels: rawptr) --- // Update GPU texture with new data - UpdateTextureRec :: proc(texture: Texture2D, rec: Rectangle, pixels: rawptr) --- // Update GPU texture rectangle with new data + LoadTexture :: proc(fileName: cstring) -> Texture2D --- // Load texture from file into GPU memory (VRAM) + LoadTextureFromImage :: proc(image: Image) -> Texture2D --- // Load texture from image data + LoadTextureCubemap :: proc(image: Image, layout: CubemapLayout) -> TextureCubemap --- // Load cubemap from image, multiple image cubemap layouts supported + LoadRenderTexture :: proc(width, height: c.int) -> RenderTexture2D --- // Load texture for rendering (framebuffer) + IsTextureValid :: proc(texture: Texture2D) -> bool --- // Check if a texture is valid + UnloadTexture :: proc(texture: Texture2D) --- // Unload texture from GPU memory (VRAM) + IsRenderTextureValid :: proc(target: RenderTexture2D) -> bool --- // Check if a render texture is valid + UnloadRenderTexture :: proc(target: RenderTexture2D) --- // Unload render texture from GPU memory (VRAM) + UpdateTexture :: proc(texture: Texture2D, pixels: rawptr) --- // Update GPU texture with new data + UpdateTextureRec :: proc(texture: Texture2D, rec: Rectangle, pixels: rawptr) --- // Update GPU texture rectangle with new data // Texture configuration functions - GenTextureMipmaps :: proc(texture: ^Texture2D) --- // Generate GPU mipmaps for a texture - SetTextureFilter :: proc(texture: Texture2D, filter: TextureFilter) --- // Set texture scaling filter mode - SetTextureWrap :: proc(texture: Texture2D, wrap: TextureWrap) --- // Set texture wrapping mode + GenTextureMipmaps :: proc(texture: ^Texture2D) --- // Generate GPU mipmaps for a texture + SetTextureFilter :: proc(texture: Texture2D, filter: TextureFilter) --- // Set texture scaling filter mode + SetTextureWrap :: proc(texture: Texture2D, wrap: TextureWrap) --- // Set texture wrapping mode - // Texture drawing functions - DrawTexture :: proc(texture: Texture2D, posX, posY: c.int, tint: Color) --- // Draw a Texture2D - DrawTextureV :: proc(texture: Texture2D, position: Vector2, tint: Color) --- // Draw a Texture2D with position defined as Vector2 - DrawTextureEx :: proc(texture: Texture2D, position: Vector2, rotation: f32, scale: f32, tint: Color) --- // Draw a Texture2D with extended parameters - DrawTextureRec :: proc(texture: Texture2D, source: Rectangle, position: Vector2, tint: Color) --- // Draw a part of a texture defined by a rectangle - DrawTexturePro :: proc(texture: Texture2D, source, dest: Rectangle, origin: Vector2, rotation: f32, tint: Color) --- // Draw a part of a texture defined by a rectangle with 'pro' parameters + // Texture drawing functions + DrawTexture :: proc(texture: Texture2D, posX, posY: c.int, tint: Color) --- // Draw a Texture2D + DrawTextureV :: proc(texture: Texture2D, position: Vector2, tint: Color) --- // Draw a Texture2D with position defined as Vector2 + DrawTextureEx :: proc(texture: Texture2D, position: Vector2, rotation: f32, scale: f32, tint: Color) --- // Draw a Texture2D with extended parameters + DrawTextureRec :: proc(texture: Texture2D, source: Rectangle, position: Vector2, tint: Color) --- // Draw a part of a texture defined by a rectangle + DrawTexturePro :: proc(texture: Texture2D, source, dest: Rectangle, origin: Vector2, rotation: f32, tint: Color) --- // Draw a part of a texture defined by a rectangle with 'pro' parameters DrawTextureNPatch :: proc(texture: Texture2D, nPatchInfo: NPatchInfo, dest: Rectangle, origin: Vector2, rotation: f32, tint: Color) --- // Draws a texture (or part of it) that stretches or shrinks nicely // Color/pixel related functions + + @(deprecated="Prefer col1 == col2") + ColorIsEqual :: proc(col1, col2: Color) --- // Check if two colors are equal + Fade :: proc(color: Color, alpha: f32) -> Color --- // Get color with alpha applied, alpha goes from 0.0f to 1.0f + ColorToInt :: proc(color: Color) -> c.uint --- // Get hexadecimal value for a Color (0xRRGGBBAA) + ColorNormalize :: proc(color: Color) -> Vector4 --- // Get Color normalized as float [0..1] + ColorFromNormalized :: proc(normalized: Vector4) -> Color --- // Get Color from normalized values [0..1] + ColorToHSV :: proc(color: Color) -> Vector3 --- // Get HSV values for a Color, hue [0..360], saturation/value [0..1] + ColorFromHSV :: proc(hue, saturation, value: f32) -> Color --- // Get a Color from HSV values, hue [0..360], saturation/value [0..1] + ColorTint :: proc(color, tint: Color) -> Color --- // Get color multiplied with another color + ColorBrightness :: proc(color: Color, factor: f32) -> Color --- // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f + ColorContrast :: proc(color: Color, contrast: f32) -> Color --- // Get color with contrast correction, contrast values between -1.0f and 1.0f + ColorAlpha :: proc(color: Color, alpha: f32) -> Color --- // Get color with alpha applied, alpha goes from 0.0f to 1.0f + ColorAlphaBlend :: proc(dst, src, tint: Color) -> Color --- // Get src alpha-blended into dst color with tint + ColorLerp :: proc(color1, color2: Color, factor: f32) -> Color --- // Get color lerp interpolation between two colors, factor [0.0f..1.0f] + GetColor :: proc(hexValue: c.uint) -> Color --- // Get Color structure from hexadecimal value + GetPixelColor :: proc(srcPtr: rawptr, format: PixelFormat) -> Color --- // Get Color from a source pixel pointer of certain format + SetPixelColor :: proc(dstPtr: rawptr, color: Color, format: PixelFormat) --- // Set color formatted into destination pixel pointer + GetPixelDataSize :: proc(width, height: c.int, format: PixelFormat) -> c.int --- // Get pixel data size in bytes for certain format + - @(deprecated = "Prefer col1 == col2") - ColorIsEqual :: proc(col1, col2: Color) --- // Check if two colors are equal - Fade :: proc(color: Color, alpha: f32) -> Color --- // Get color with alpha applied, alpha goes from 0.0f to 1.0f - ColorToInt :: proc(color: Color) -> c.uint --- // Get hexadecimal value for a Color (0xRRGGBBAA) - ColorNormalize :: proc(color: Color) -> Vector4 --- // Get Color normalized as float [0..1] - ColorFromNormalized :: proc(normalized: Vector4) -> Color --- // Get Color from normalized values [0..1] - ColorToHSV :: proc(color: Color) -> Vector3 --- // Get HSV values for a Color, hue [0..360], saturation/value [0..1] - ColorFromHSV :: proc(hue, saturation, value: f32) -> Color --- // Get a Color from HSV values, hue [0..360], saturation/value [0..1] - ColorTint :: proc(color, tint: Color) -> Color --- // Get color multiplied with another color - ColorBrightness :: proc(color: Color, factor: f32) -> Color --- // Get color with brightness correction, brightness factor goes from -1.0f to 1.0f - ColorContrast :: proc(color: Color, contrast: f32) -> Color --- // Get color with contrast correction, contrast values between -1.0f and 1.0f - ColorAlpha :: proc(color: Color, alpha: f32) -> Color --- // Get color with alpha applied, alpha goes from 0.0f to 1.0f - ColorAlphaBlend :: proc(dst, src, tint: Color) -> Color --- // Get src alpha-blended into dst color with tint - ColorLerp :: proc(color1, color2: Color, factor: f32) -> Color --- // Get color lerp interpolation between two colors, factor [0.0f..1.0f] - GetColor :: proc(hexValue: c.uint) -> Color --- // Get Color structure from hexadecimal value - GetPixelColor :: proc(srcPtr: rawptr, format: PixelFormat) -> Color --- // Get Color from a source pixel pointer of certain format - SetPixelColor :: proc(dstPtr: rawptr, color: Color, format: PixelFormat) --- // Set color formatted into destination pixel pointer - GetPixelDataSize :: proc(width, height: c.int, format: PixelFormat) -> c.int --- // Get pixel data size in bytes for certain format //------------------------------------------------------------------------------------ @@ -1396,72 +1430,72 @@ foreign lib { // Font loading/unloading functions - GetFontDefault :: proc() -> Font --- // Get the default Font - LoadFont :: proc(fileName: cstring) -> Font --- // Load font from file into GPU memory (VRAM) - LoadFontEx :: proc(fileName: cstring, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int) -> Font --- // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height - LoadFontFromImage :: proc(image: Image, key: Color, firstChar: rune) -> Font --- // Load font from Image (XNA style) - LoadFontFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int) -> Font --- // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' - IsFontValid :: proc(font: Font) -> bool --- // Check if a font is valid (font data loaded, WARNING: GPU texture not checked) - LoadFontData :: proc(fileData: rawptr, dataSize: c.int, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int, type: FontType) -> [^]GlyphInfo --- // Load font data for further use - GenImageFontAtlas :: proc(glyphs: [^]GlyphInfo, glyphRecs: ^[^]Rectangle, codepointCount: c.int, fontSize: c.int, padding: c.int, packMethod: c.int) -> Image --- // Generate image font atlas using chars info - UnloadFontData :: proc(glyphs: [^]GlyphInfo, glyphCount: c.int) --- // Unload font chars info data (RAM) - UnloadFont :: proc(font: Font) --- // Unload font from GPU memory (VRAM) - ExportFontAsCode :: proc(font: Font, fileName: cstring) -> bool --- // Export font as code file, returns true on success + GetFontDefault :: proc() -> Font --- // Get the default Font + LoadFont :: proc(fileName: cstring) -> Font --- // Load font from file into GPU memory (VRAM) + LoadFontEx :: proc(fileName: cstring, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int) -> Font --- // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height + LoadFontFromImage :: proc(image: Image, key: Color, firstChar: rune) -> Font --- // Load font from Image (XNA style) + LoadFontFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int) -> Font --- // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' + IsFontValid :: proc(font: Font) -> bool --- // Check if a font is valid (font data loaded, WARNING: GPU texture not checked) + LoadFontData :: proc(fileData: rawptr, dataSize: c.int, fontSize: c.int, codepoints: [^]rune, codepointCount: c.int, type: FontType) -> [^]GlyphInfo --- // Load font data for further use + GenImageFontAtlas :: proc(glyphs: [^]GlyphInfo, glyphRecs: ^[^]Rectangle, codepointCount: c.int, fontSize: c.int, padding: c.int, packMethod: c.int) -> Image --- // Generate image font atlas using chars info + UnloadFontData :: proc(glyphs: [^]GlyphInfo, glyphCount: c.int) --- // Unload font chars info data (RAM) + UnloadFont :: proc(font: Font) --- // Unload font from GPU memory (VRAM) + ExportFontAsCode :: proc(font: Font, fileName: cstring) -> bool --- // Export font as code file, returns true on success // Text drawing functions - DrawFPS :: proc(posX, posY: c.int) --- // Draw current FPS - DrawText :: proc(text: cstring, posX, posY: c.int, fontSize: c.int, color: Color) --- // Draw text (using default font) - DrawTextEx :: proc(font: Font, text: cstring, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw text using font and additional parameters - DrawTextPro :: proc(font: Font, text: cstring, position, origin: Vector2, rotation: f32, fontSize: f32, spacing: f32, tint: Color) --- // Draw text using Font and pro parameters (rotation) - DrawTextCodepoint :: proc(font: Font, codepoint: rune, position: Vector2, fontSize: f32, tint: Color) --- // Draw one character (codepoint) - DrawTextCodepoints :: proc(font: Font, codepoints: [^]rune, codepointCount: c.int, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw multiple character (codepoint) + DrawFPS :: proc(posX, posY: c.int) --- // Draw current FPS + DrawText :: proc(text: cstring, posX, posY: c.int, fontSize: c.int, color: Color) --- // Draw text (using default font) + DrawTextEx :: proc(font: Font, text: cstring, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw text using font and additional parameters + DrawTextPro :: proc(font: Font, text: cstring, position, origin: Vector2, rotation: f32, fontSize: f32, spacing: f32, tint: Color) --- // Draw text using Font and pro parameters (rotation) + DrawTextCodepoint :: proc(font: Font, codepoint: rune, position: Vector2, fontSize: f32, tint: Color) --- // Draw one character (codepoint) + DrawTextCodepoints :: proc(font: Font, codepoints: [^]rune, codepointCount: c.int, position: Vector2, fontSize: f32, spacing: f32, tint: Color) --- // Draw multiple character (codepoint) // Text font info functions - SetTextLineSpacing :: proc(spacing: c.int) --- // Set vertical line spacing when drawing with line-breaks - MeasureText :: proc(text: cstring, fontSize: c.int) -> c.int --- // Measure string width for default font - MeasureTextEx :: proc(font: Font, text: cstring, fontSize: f32, spacing: f32) -> Vector2 --- // Measure string size for Font - GetGlyphIndex :: proc(font: Font, codepoint: rune) -> c.int --- // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found - GetGlyphInfo :: proc(font: Font, codepoint: rune) -> GlyphInfo --- // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found - GetGlyphAtlasRec :: proc(font: Font, codepoint: rune) -> Rectangle --- // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found + SetTextLineSpacing :: proc(spacing: c.int) --- // Set vertical line spacing when drawing with line-breaks + MeasureText :: proc(text: cstring, fontSize: c.int) -> c.int --- // Measure string width for default font + MeasureTextEx :: proc(font: Font, text: cstring, fontSize: f32, spacing: f32) -> Vector2 --- // Measure string size for Font + GetGlyphIndex :: proc(font: Font, codepoint: rune) -> c.int --- // Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found + GetGlyphInfo :: proc(font: Font, codepoint: rune) -> GlyphInfo --- // Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found + GetGlyphAtlasRec :: proc(font: Font, codepoint: rune) -> Rectangle --- // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found // Text codepoints management functions (unicode characters) - LoadUTF8 :: proc(codepoints: [^]rune, length: c.int) -> [^]byte --- // Load UTF-8 text encoded from codepoints array - UnloadUTF8 :: proc(text: [^]byte) --- // Unload UTF-8 text encoded from codepoints array - LoadCodepoints :: proc(text: cstring, count: ^c.int) -> [^]rune --- // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter - UnloadCodepoints :: proc(codepoints: [^]rune) --- // Unload codepoints data from memory - GetCodepointCount :: proc(text: cstring) -> c.int --- // Get total number of codepoints in a UTF-8 encoded string - GetCodepoint :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure - GetCodepointNext :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure - GetCodepointPrevious :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure - CodepointToUTF8 :: proc(codepoint: rune, utf8Size: ^c.int) -> cstring --- // Encode one codepoint into UTF-8 byte array (array length returned as parameter) + LoadUTF8 :: proc(codepoints: [^]rune, length: c.int) -> [^]byte --- // Load UTF-8 text encoded from codepoints array + UnloadUTF8 :: proc(text: [^]byte) --- // Unload UTF-8 text encoded from codepoints array + LoadCodepoints :: proc(text: cstring, count: ^c.int) -> [^]rune --- // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter + UnloadCodepoints :: proc(codepoints: [^]rune) --- // Unload codepoints data from memory + GetCodepointCount :: proc(text: cstring) -> c.int --- // Get total number of codepoints in a UTF-8 encoded string + GetCodepoint :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + GetCodepointNext :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + GetCodepointPrevious :: proc(text: cstring, codepointSize: ^c.int) -> rune --- // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure + CodepointToUTF8 :: proc(codepoint: rune, utf8Size: ^c.int) -> cstring --- // 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! - TextCopy :: proc(dst: [^]byte, src: cstring) -> c.int --- // Copy one string to another, returns bytes copied - TextIsEqual :: proc(text1, text2: cstring) -> bool --- // Check if two text string are equal - TextLength :: proc(text: cstring) -> c.uint --- // Get text length, checks for '\0' ending + TextCopy :: proc(dst: [^]byte, src: cstring) -> c.int --- // Copy one string to another, returns bytes copied + TextIsEqual :: proc(text1, text2: cstring) -> bool --- // Check if two text string are equal + TextLength :: proc(text: cstring) -> c.uint --- // Get text length, checks for '\0' ending // TextFormat is defined at the bottom of this file - TextSubtext :: proc(text: cstring, position: c.int, length: c.int) -> cstring --- // Get a piece of a text string - TextReplace :: proc(text: [^]byte, replace, by: cstring) -> [^]byte --- // Replace text string (WARNING: memory must be freed!) - TextInsert :: proc(text, insert: cstring, position: c.int) -> [^]byte --- // Insert text in a position (WARNING: memory must be freed!) - TextJoin :: proc(textList: [^]cstring, count: c.int, delimiter: cstring) -> cstring --- // Join text strings with delimiter - TextSplit :: proc(text: cstring, delimiter: byte, count: ^c.int) -> [^]cstring --- // Split text into multiple strings - TextAppend :: proc(text: [^]byte, append: cstring, position: ^c.int) --- // Append text at specific position and move cursor! - TextFindIndex :: proc(text, find: cstring) -> c.int --- // Find first text occurrence within a string - TextToUpper :: proc(text: cstring) -> cstring --- // Get upper case version of provided string - TextToLower :: proc(text: cstring) -> cstring --- // Get lower case version of provided string - TextToPascal :: proc(text: cstring) -> cstring --- // Get Pascal case notation version of provided string - TextToSnake :: proc(text: cstring) -> cstring --- // Get Snake case notation version of provided string - TextToCamel :: proc(text: cstring) -> cstring --- // Get Camel case notation version of provided string + TextSubtext :: proc(text: cstring, position: c.int, length: c.int) -> cstring --- // Get a piece of a text string + TextReplace :: proc(text: [^]byte, replace, by: cstring) -> [^]byte --- // Replace text string (WARNING: memory must be freed!) + TextInsert :: proc(text, insert: cstring, position: c.int) -> [^]byte --- // Insert text in a position (WARNING: memory must be freed!) + TextJoin :: proc(textList: [^]cstring, count: c.int, delimiter: cstring) -> cstring --- // Join text strings with delimiter + TextSplit :: proc(text: cstring, delimiter: byte, count: ^c.int) -> [^]cstring --- // Split text into multiple strings + TextAppend :: proc(text: [^]byte, append: cstring, position: ^c.int) --- // Append text at specific position and move cursor! + TextFindIndex :: proc(text, find: cstring) -> c.int --- // Find first text occurrence within a string + TextToUpper :: proc(text: cstring) -> cstring --- // Get upper case version of provided string + TextToLower :: proc(text: cstring) -> cstring --- // Get lower case version of provided string + TextToPascal :: proc(text: cstring) -> cstring --- // Get Pascal case notation version of provided string + TextToSnake :: proc(text: cstring) -> cstring --- // Get Snake case notation version of provided string + TextToCamel :: proc(text: cstring) -> cstring --- // Get Camel case notation version of provided string - TextToInteger :: proc(text: cstring) -> c.int --- // Get integer value from text (negative values not supported) - TextToFloat :: proc(text: cstring) -> f32 --- // Get float value from text (negative values not supported) + TextToInteger :: proc(text: cstring) -> c.int --- // Get integer value from text (negative values not supported) + TextToFloat :: proc(text: cstring) -> f32 --- // Get float value from text (negative values not supported) //------------------------------------------------------------------------------------ @@ -1470,27 +1504,27 @@ foreign lib { // Basic geometric 3D shapes drawing functions - DrawLine3D :: proc(startPos, endPos: Vector3, color: Color) --- // Draw a line in 3D world space - DrawPoint3D :: proc(position: Vector3, color: Color) --- // Draw a point in 3D space, actually a small line - DrawCircle3D :: proc(center: Vector3, radius: f32, rotationAxis: Vector3, rotationAngle: f32, color: Color) --- // Draw a circle in 3D world space - DrawTriangle3D :: proc(v1, v2, v3: Vector3, color: Color) --- // Draw a color-filled triangle (vertex in counter-clockwise order!) - DrawTriangleStrip3D :: proc(points: [^]Vector3, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points - DrawCube :: proc(position: Vector3, width, height, length: f32, color: Color) --- // Draw cube - DrawCubeV :: proc(position: Vector3, size: Vector3, color: Color) --- // Draw cube (Vector version) - DrawCubeWires :: proc(position: Vector3, width, height, length: f32, color: Color) --- // Draw cube wires - DrawCubeWiresV :: proc(position, size: Vector3, color: Color) --- // Draw cube wires (Vector version) - DrawSphere :: proc(centerPos: Vector3, radius: f32, color: Color) --- // Draw sphere - DrawSphereEx :: proc(centerPos: Vector3, radius: f32, rings, slices: c.int, color: Color) --- // Draw sphere with extended parameters - DrawSphereWires :: proc(centerPos: Vector3, radius: f32, rings, slices: c.int, color: Color) --- // Draw sphere wires - DrawCylinder :: proc(position: Vector3, radiusTop, radiusBottom: f32, height: f32, slices: c.int, color: Color) --- // Draw a cylinder/cone - DrawCylinderEx :: proc(startPos, endPos: Vector3, startRadius, endRadius: f32, sides: c.int, color: Color) --- // Draw a cylinder with base at startPos and top at endPos - DrawCylinderWires :: proc(position: Vector3, radiusTop, radiusBottom, height: f32, slices: c.int, color: Color) --- // Draw a cylinder/cone wires - DrawCylinderWiresEx :: proc(startPos, endPos: Vector3, startRadius, endRadius: f32, sides: c.int, color: Color) --- // Draw a cylinder wires with base at startPos and top at endPos - DrawCapsule :: proc(startPos, endPos: Vector3, radius: f32, slices, rings: c.int, color: Color) --- // Draw a capsule with the center of its sphere caps at startPos and endPos - DrawCapsuleWires :: proc(startPos, endPos: Vector3, radius: f32, slices, rings: c.int, color: Color) --- // Draw capsule wireframe with the center of its sphere caps at startPos and endPos - DrawPlane :: proc(centerPos: Vector3, size: Vector2, color: Color) --- // Draw a plane XZ - DrawRay :: proc(ray: Ray, color: Color) --- // Draw a ray line - DrawGrid :: proc(slices: c.int, spacing: f32) --- // Draw a grid (centered at (0, 0, 0)) + DrawLine3D :: proc(startPos, endPos: Vector3, color: Color) --- // Draw a line in 3D world space + DrawPoint3D :: proc(position: Vector3, color: Color) --- // Draw a point in 3D space, actually a small line + DrawCircle3D :: proc(center: Vector3, radius: f32, rotationAxis: Vector3, rotationAngle: f32, color: Color) --- // Draw a circle in 3D world space + DrawTriangle3D :: proc(v1, v2, v3: Vector3, color: Color) --- // Draw a color-filled triangle (vertex in counter-clockwise order!) + DrawTriangleStrip3D :: proc(points: [^]Vector3, pointCount: c.int, color: Color) --- // Draw a triangle strip defined by points + DrawCube :: proc(position: Vector3, width, height, length: f32, color: Color) --- // Draw cube + DrawCubeV :: proc(position: Vector3, size: Vector3, color: Color) --- // Draw cube (Vector version) + DrawCubeWires :: proc(position: Vector3, width, height, length: f32, color: Color) --- // Draw cube wires + DrawCubeWiresV :: proc(position, size: Vector3, color: Color) --- // Draw cube wires (Vector version) + DrawSphere :: proc(centerPos: Vector3, radius: f32, color: Color) --- // Draw sphere + DrawSphereEx :: proc(centerPos: Vector3, radius: f32, rings, slices: c.int, color: Color) --- // Draw sphere with extended parameters + DrawSphereWires :: proc(centerPos: Vector3, radius: f32, rings, slices: c.int, color: Color) --- // Draw sphere wires + DrawCylinder :: proc(position: Vector3, radiusTop, radiusBottom: f32, height: f32, slices: c.int, color: Color) --- // Draw a cylinder/cone + DrawCylinderEx :: proc(startPos, endPos: Vector3, startRadius, endRadius: f32, sides: c.int, color: Color) --- // Draw a cylinder with base at startPos and top at endPos + DrawCylinderWires :: proc(position: Vector3, radiusTop, radiusBottom, height: f32, slices: c.int, color: Color) --- // Draw a cylinder/cone wires + DrawCylinderWiresEx :: proc(startPos, endPos: Vector3, startRadius, endRadius: f32, sides: c.int, color: Color) --- // Draw a cylinder wires with base at startPos and top at endPos + DrawCapsule :: proc(startPos, endPos: Vector3, radius: f32, slices, rings: c.int, color: Color) --- // Draw a capsule with the center of its sphere caps at startPos and endPos + DrawCapsuleWires :: proc(startPos, endPos: Vector3, radius: f32, slices, rings: c.int, color: Color) --- // Draw capsule wireframe with the center of its sphere caps at startPos and endPos + DrawPlane :: proc(centerPos: Vector3, size: Vector2, color: Color) --- // Draw a plane XZ + DrawRay :: proc(ray: Ray, color: Color) --- // Draw a ray line + DrawGrid :: proc(slices: c.int, spacing: f32) --- // Draw a grid (centered at (0, 0, 0)) //------------------------------------------------------------------------------------ // Model 3d Loading and Drawing Functions (Module: models) @@ -1498,79 +1532,79 @@ foreign lib { // Model management functions - LoadModel :: proc(fileName: cstring) -> Model --- // Load model from files (meshes and materials) - LoadModelFromMesh :: proc(mesh: Mesh) -> Model --- // Load model from generated mesh (default material) - IsModelValid :: proc(model: Model) -> bool --- // Check if a model is valid (loaded in GPU, VAO/VBOs) - UnloadModel :: proc(model: Model) --- // Unload model (including meshes) from memory (RAM and/or VRAM) + LoadModel :: proc(fileName: cstring) -> Model --- // Load model from files (meshes and materials) + LoadModelFromMesh :: proc(mesh: Mesh) -> Model --- // Load model from generated mesh (default material) + IsModelValid :: proc(model: Model) -> bool --- // Check if a model is valid (loaded in GPU, VAO/VBOs) + UnloadModel :: proc(model: Model) --- // Unload model (including meshes) from memory (RAM and/or VRAM) GetModelBoundingBox :: proc(model: Model) -> BoundingBox --- // Compute model bounding box limits (considers all meshes) // Model drawing functions - DrawModel :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model (with texture if set) - DrawModelEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model with extended parameters - DrawModelWires :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model wires (with texture if set) - DrawModelWiresEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model wires (with texture if set) with extended parameters - DrawModelPoints :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model as points - DrawModelPointsEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model as points with extended parameters - DrawBoundingBox :: proc(box: BoundingBox, color: Color) --- // Draw bounding box (wires) - DrawBillboard :: proc(camera: Camera, texture: Texture2D, position: Vector3, scale: f32, tint: Color) --- // Draw a billboard texture - DrawBillboardRec :: proc(camera: Camera, texture: Texture2D, source: Rectangle, position: Vector3, size: Vector2, tint: Color) --- // Draw a billboard texture defined by source - DrawBillboardPro :: proc(camera: Camera, texture: Texture2D, source: Rectangle, position: Vector3, up: Vector3, size: Vector2, origin: Vector2, rotation: f32, tint: Color) --- // Draw a billboard texture defined by source and rotation + DrawModel :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model (with texture if set) + DrawModelEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model with extended parameters + DrawModelWires :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model wires (with texture if set) + DrawModelWiresEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model wires (with texture if set) with extended parameters + DrawModelPoints :: proc(model: Model, position: Vector3, scale: f32, tint: Color) --- // Draw a model as points + DrawModelPointsEx :: proc(model: Model, position: Vector3, rotationAxis: Vector3, rotationAngle: f32, scale: Vector3, tint: Color) --- // Draw a model as points with extended parameters + DrawBoundingBox :: proc(box: BoundingBox, color: Color) --- // Draw bounding box (wires) + DrawBillboard :: proc(camera: Camera, texture: Texture2D, position: Vector3, scale: f32, tint: Color) --- // Draw a billboard texture + DrawBillboardRec :: proc(camera: Camera, texture: Texture2D, source: Rectangle, position: Vector3, size: Vector2, tint: Color) --- // Draw a billboard texture defined by source + DrawBillboardPro :: proc(camera: Camera, texture: Texture2D, source: Rectangle, position: Vector3, up: Vector3, size: Vector2, origin: Vector2, rotation: f32, tint: Color) --- // Draw a billboard texture defined by source and rotation // Mesh management functions - UploadMesh :: proc(mesh: ^Mesh, is_dynamic: bool) --- // Upload mesh vertex data in GPU and provide VAO/VBO ids - UpdateMeshBuffer :: proc(mesh: Mesh, index: c.int, data: rawptr, dataSize: c.int, offset: c.int) --- // Update mesh vertex data in GPU for a specific buffer index - UnloadMesh :: proc(mesh: Mesh) --- // Unload mesh data from CPU and GPU - DrawMesh :: proc(mesh: Mesh, material: Material, transform: Matrix) --- // Draw a 3d mesh with material and transform - DrawMeshInstanced :: proc(mesh: Mesh, material: Material, transforms: [^]Matrix, instances: c.int) --- // Draw multiple mesh instances with material and different transforms - GetMeshBoundingBox :: proc(mesh: Mesh) -> BoundingBox --- // Compute mesh bounding box limits - GenMeshTangents :: proc(mesh: ^Mesh) --- // Compute mesh tangents - ExportMesh :: proc(mesh: Mesh, fileName: cstring) -> bool --- // Export mesh data to file, returns true on success - ExportMeshAsCode :: proc(mesh: Mesh, fileName: cstring) -> bool --- // Export mesh as code file (.h) defining multiple arrays of vertex attributes + UploadMesh :: proc(mesh: ^Mesh, is_dynamic: bool) --- // Upload mesh vertex data in GPU and provide VAO/VBO ids + UpdateMeshBuffer :: proc(mesh: Mesh, index: c.int, data: rawptr, dataSize: c.int, offset: c.int) --- // Update mesh vertex data in GPU for a specific buffer index + UnloadMesh :: proc(mesh: Mesh) --- // Unload mesh data from CPU and GPU + DrawMesh :: proc(mesh: Mesh, material: Material, transform: Matrix) --- // Draw a 3d mesh with material and transform + DrawMeshInstanced :: proc(mesh: Mesh, material: Material, transforms: [^]Matrix, instances: c.int) --- // Draw multiple mesh instances with material and different transforms + GetMeshBoundingBox :: proc(mesh: Mesh) -> BoundingBox --- // Compute mesh bounding box limits + GenMeshTangents :: proc(mesh: ^Mesh) --- // Compute mesh tangents + ExportMesh :: proc(mesh: Mesh, fileName: cstring) -> bool --- // Export mesh data to file, returns true on success + ExportMeshAsCode :: proc(mesh: Mesh, fileName: cstring) -> bool --- // Export mesh as code file (.h) defining multiple arrays of vertex attributes // Mesh generation functions - GenMeshPoly :: proc(sides: c.int, radius: f32) -> Mesh --- // Generate polygonal mesh - GenMeshPlane :: proc(width, length: f32, resX, resZ: c.int) -> Mesh --- // Generate plane mesh (with subdivisions) - GenMeshCube :: proc(width, height, length: f32) -> Mesh --- // Generate cuboid mesh - GenMeshSphere :: proc(radius: f32, rings, slices: c.int) -> Mesh --- // Generate sphere mesh (standard sphere) - GenMeshHemiSphere :: proc(radius: f32, rings, slices: c.int) -> Mesh --- // Generate half-sphere mesh (no bottom cap) - GenMeshCylinder :: proc(radius, height: f32, slices: c.int) -> Mesh --- // Generate cylinder mesh - GenMeshCone :: proc(radius, height: f32, slices: c.int) -> Mesh --- // Generate cone/pyramid mesh - GenMeshTorus :: proc(radius, size: f32, radSeg, sides: c.int) -> Mesh --- // Generate torus mesh - GenMeshKnot :: proc(radius, size: f32, radSeg, sides: c.int) -> Mesh --- // Generate trefoil knot mesh - GenMeshHeightmap :: proc(heightmap: Image, size: Vector3) -> Mesh --- // Generate heightmap mesh from image data - GenMeshCubicmap :: proc(cubicmap: Image, cubeSize: Vector3) -> Mesh --- // Generate cubes-based map mesh from image data + GenMeshPoly :: proc(sides: c.int, radius: f32) -> Mesh --- // Generate polygonal mesh + GenMeshPlane :: proc(width, length: f32, resX, resZ: c.int) -> Mesh --- // Generate plane mesh (with subdivisions) + GenMeshCube :: proc(width, height, length: f32) -> Mesh --- // Generate cuboid mesh + GenMeshSphere :: proc(radius: f32, rings, slices: c.int) -> Mesh --- // Generate sphere mesh (standard sphere) + GenMeshHemiSphere :: proc(radius: f32, rings, slices: c.int) -> Mesh --- // Generate half-sphere mesh (no bottom cap) + GenMeshCylinder :: proc(radius, height: f32, slices: c.int) -> Mesh --- // Generate cylinder mesh + GenMeshCone :: proc(radius, height: f32, slices: c.int) -> Mesh --- // Generate cone/pyramid mesh + GenMeshTorus :: proc(radius, size: f32, radSeg, sides: c.int) -> Mesh --- // Generate torus mesh + GenMeshKnot :: proc(radius, size: f32, radSeg, sides: c.int) -> Mesh --- // Generate trefoil knot mesh + GenMeshHeightmap :: proc(heightmap: Image, size: Vector3) -> Mesh --- // Generate heightmap mesh from image data + GenMeshCubicmap :: proc(cubicmap: Image, cubeSize: Vector3) -> Mesh --- // Generate cubes-based map mesh from image data // Material loading/unloading functions - LoadMaterials :: proc(fileName: cstring, materialCount: ^c.int) -> [^]Material --- // Load materials from model file - LoadMaterialDefault :: proc() -> Material --- // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) - IsMaterialValid :: proc(material: Material) -> bool --- // Check if a material is valid (shader assigned, map textures loaded in GPU) - UnloadMaterial :: proc(material: Material) --- // Unload material from GPU memory (VRAM) - SetMaterialTexture :: proc(material: ^Material, mapType: MaterialMapIndex, texture: Texture2D) --- // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) - SetModelMeshMaterial :: proc(model: ^Model, meshId: c.int, materialId: c.int) --- // Set material for a mesh + LoadMaterials :: proc(fileName: cstring, materialCount: ^c.int) -> [^]Material --- // Load materials from model file + LoadMaterialDefault :: proc() -> Material --- // Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) + IsMaterialValid :: proc(material: Material) -> bool --- // Check if a material is valid (shader assigned, map textures loaded in GPU) + UnloadMaterial :: proc(material: Material) --- // Unload material from GPU memory (VRAM) + SetMaterialTexture :: proc(material: ^Material, mapType: MaterialMapIndex, texture: Texture2D) --- // Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) + SetModelMeshMaterial :: proc(model: ^Model, meshId: c.int, materialId: c.int) --- // Set material for a mesh // Model animations loading/unloading functions - LoadModelAnimations :: proc(fileName: cstring, animCount: ^c.int) -> [^]ModelAnimation --- // Load model animations from file - UpdateModelAnimation :: proc(model: Model, anim: ModelAnimation, frame: c.int) --- // Update model animation pose (CPU) - UpdateModelAnimationBones :: proc(model: Model, anim: ModelAnimation, frame: c.int) --- // Update model animation mesh bone matrices (GPU skinning) - UnloadModelAnimation :: proc(anim: ModelAnimation) --- // Unload animation data - UnloadModelAnimations :: proc(animations: [^]ModelAnimation, animCount: c.int) --- // Unload animation array data - IsModelAnimationValid :: proc(model: Model, anim: ModelAnimation) -> bool --- // Check model animation skeleton match + LoadModelAnimations :: proc(fileName: cstring, animCount: ^c.int) -> [^]ModelAnimation --- // Load model animations from file + UpdateModelAnimation :: proc(model: Model, anim: ModelAnimation, frame: c.int) --- // Update model animation pose (CPU) + UpdateModelAnimationBones :: proc(model: Model, anim: ModelAnimation, frame: c.int) --- // Update model animation mesh bone matrices (GPU skinning) + UnloadModelAnimation :: proc(anim: ModelAnimation) --- // Unload animation data + UnloadModelAnimations :: proc(animations: [^]ModelAnimation, animCount: c.int) --- // Unload animation array data + IsModelAnimationValid :: proc(model: Model, anim: ModelAnimation) -> bool --- // Check model animation skeleton match // Collision detection functions - CheckCollisionSpheres :: proc(center1: Vector3, radius1: f32, center2: Vector3, radius2: f32) -> bool --- // Check collision between two spheres - CheckCollisionBoxes :: proc(box1, box2: BoundingBox) -> bool --- // Check collision between two bounding boxes - CheckCollisionBoxSphere :: proc(box: BoundingBox, center: Vector3, radius: f32) -> bool --- // Check collision between box and sphere - GetRayCollisionSphere :: proc(ray: Ray, center: Vector3, radius: f32) -> RayCollision --- // Get collision info between ray and sphere - GetRayCollisionBox :: proc(ray: Ray, box: BoundingBox) -> RayCollision --- // Get collision info between ray and box - GetRayCollisionMesh :: proc(ray: Ray, mesh: Mesh, transform: Matrix) -> RayCollision --- // Get collision info between ray and mesh - GetRayCollisionTriangle :: proc(ray: Ray, p1, p2, p3: Vector3) -> RayCollision --- // Get collision info between ray and triangle - GetRayCollisionQuad :: proc(ray: Ray, p1, p2, p3, p4: Vector3) -> RayCollision --- // Get collision info between ray and quad + CheckCollisionSpheres :: proc(center1: Vector3, radius1: f32, center2: Vector3, radius2: f32) -> bool --- // Check collision between two spheres + CheckCollisionBoxes :: proc(box1, box2: BoundingBox) -> bool --- // Check collision between two bounding boxes + CheckCollisionBoxSphere :: proc(box: BoundingBox, center: Vector3, radius: f32) -> bool --- // Check collision between box and sphere + GetRayCollisionSphere :: proc(ray: Ray, center: Vector3, radius: f32) -> RayCollision --- // Get collision info between ray and sphere + GetRayCollisionBox :: proc(ray: Ray, box: BoundingBox) -> RayCollision --- // Get collision info between ray and box + GetRayCollisionMesh :: proc(ray: Ray, mesh: Mesh, transform: Matrix) -> RayCollision --- // Get collision info between ray and mesh + GetRayCollisionTriangle :: proc(ray: Ray, p1, p2, p3: Vector3) -> RayCollision --- // Get collision info between ray and triangle + GetRayCollisionQuad :: proc(ray: Ray, p1, p2, p3, p4: Vector3) -> RayCollision --- // Get collision info between ray and quad //------------------------------------------------------------------------------------ // Audio Loading and Playing Functions (Module: audio) @@ -1578,81 +1612,81 @@ foreign lib { // Audio device management functions - InitAudioDevice :: proc() --- // Initialize audio device and context - CloseAudioDevice :: proc() --- // Close the audio device and context - IsAudioDeviceReady :: proc() -> bool --- // Check if audio device has been initialized successfully - SetMasterVolume :: proc(volume: f32) --- // Set master volume (listener) - GetMasterVolume :: proc() -> f32 --- // Get master volume (listener) + InitAudioDevice :: proc() --- // Initialize audio device and context + CloseAudioDevice :: proc() --- // Close the audio device and context + IsAudioDeviceReady :: proc() -> bool --- // Check if audio device has been initialized successfully + SetMasterVolume :: proc(volume: f32) --- // Set master volume (listener) + GetMasterVolume :: proc() -> f32 --- // Get master volume (listener) // Wave/Sound loading/unloading functions - LoadWave :: proc(fileName: cstring) -> Wave --- // Load wave data from file + LoadWave :: proc(fileName: cstring) -> Wave --- // Load wave data from file LoadWaveFromMemory :: proc(fileType: cstring, fileData: rawptr, dataSize: c.int) -> Wave --- // Load wave from memory buffer, fileType refers to extension: i.e. '.wav' - IsWaveValid :: proc(wave: Wave) -> bool --- // Checks if wave data is // Checks if wave data is valid (data loaded and parameters) - LoadSound :: proc(fileName: cstring) -> Sound --- // Load sound from file - LoadSoundFromWave :: proc(wave: Wave) -> Sound --- // Load sound from wave data - LoadSoundAlias :: proc(source: Sound) -> Sound --- // Create a new sound that shares the same sample data as the source sound, does not own the sound data - IsSoundValid :: proc(sound: Sound) -> bool --- // Checks if a sound is valid (data loaded and buffers initialized) - UpdateSound :: proc(sound: Sound, data: rawptr, frameCount: c.int) --- // Update sound buffer with new data - UnloadWave :: proc(wave: Wave) --- // Unload wave data - UnloadSound :: proc(sound: Sound) --- // Unload sound - UnloadSoundAlias :: proc(alias: Sound) --- // Unload a sound alias (does not deallocate sample data) - ExportWave :: proc(wave: Wave, fileName: cstring) -> bool --- // Export wave data to file, returns true on success - ExportWaveAsCode :: proc(wave: Wave, fileName: cstring) -> bool --- // Export wave sample data to code (.h), returns true on success + IsWaveValid :: proc(wave: Wave) -> bool --- // Checks if wave data is // Checks if wave data is valid (data loaded and parameters) + LoadSound :: proc(fileName: cstring) -> Sound --- // Load sound from file + LoadSoundFromWave :: proc(wave: Wave) -> Sound --- // Load sound from wave data + LoadSoundAlias :: proc(source: Sound) -> Sound --- // Create a new sound that shares the same sample data as the source sound, does not own the sound data + IsSoundValid :: proc(sound: Sound) -> bool --- // Checks if a sound is valid (data loaded and buffers initialized) + UpdateSound :: proc(sound: Sound, data: rawptr, frameCount: c.int) --- // Update sound buffer with new data + UnloadWave :: proc(wave: Wave) --- // Unload wave data + UnloadSound :: proc(sound: Sound) --- // Unload sound + UnloadSoundAlias :: proc(alias: Sound) --- // Unload a sound alias (does not deallocate sample data) + ExportWave :: proc(wave: Wave, fileName: cstring) -> bool --- // Export wave data to file, returns true on success + ExportWaveAsCode :: proc(wave: Wave, fileName: cstring) -> bool --- // Export wave sample data to code (.h), returns true on success // Wave/Sound management functions - PlaySound :: proc(sound: Sound) --- // Play a sound - StopSound :: proc(sound: Sound) --- // Stop playing a sound - PauseSound :: proc(sound: Sound) --- // Pause a sound - ResumeSound :: proc(sound: Sound) --- // Resume a paused sound - IsSoundPlaying :: proc(sound: Sound) -> bool --- // Check if a sound is currently playing - SetSoundVolume :: proc(sound: Sound, volume: f32) --- // Set volume for a sound (1.0 is max level) - SetSoundPitch :: proc(sound: Sound, pitch: f32) --- // Set pitch for a sound (1.0 is base level) - SetSoundPan :: proc(sound: Sound, pan: f32) --- // Set pan for a sound (0.5 is center) - WaveCopy :: proc(wave: Wave) -> Wave --- // Copy a wave to a new wave - WaveCrop :: proc(wave: ^Wave, initFrame, finalFrame: c.int) --- // Crop a wave to defined samples range - WaveFormat :: proc(wave: ^Wave, sampleRate, sampleSize: c.int, channels: c.int) --- // Convert wave data to desired format - LoadWaveSamples :: proc(wave: Wave) -> [^]f32 --- // Load samples data from wave as a 32bit float data array - UnloadWaveSamples :: proc(samples: [^]f32) --- // Unload samples data loaded with LoadWaveSamples() + PlaySound :: proc(sound: Sound) --- // Play a sound + StopSound :: proc(sound: Sound) --- // Stop playing a sound + PauseSound :: proc(sound: Sound) --- // Pause a sound + ResumeSound :: proc(sound: Sound) --- // Resume a paused sound + IsSoundPlaying :: proc(sound: Sound) -> bool --- // Check if a sound is currently playing + SetSoundVolume :: proc(sound: Sound, volume: f32) --- // Set volume for a sound (1.0 is max level) + SetSoundPitch :: proc(sound: Sound, pitch: f32) --- // Set pitch for a sound (1.0 is base level) + SetSoundPan :: proc(sound: Sound, pan: f32) --- // Set pan for a sound (0.5 is center) + WaveCopy :: proc(wave: Wave) -> Wave --- // Copy a wave to a new wave + WaveCrop :: proc(wave: ^Wave, initFrame, finalFrame: c.int) --- // Crop a wave to defined samples range + WaveFormat :: proc(wave: ^Wave, sampleRate, sampleSize: c.int, channels: c.int) --- // Convert wave data to desired format + LoadWaveSamples :: proc(wave: Wave) -> [^]f32 --- // Load samples data from wave as a 32bit float data array + UnloadWaveSamples :: proc(samples: [^]f32) --- // Unload samples data loaded with LoadWaveSamples() // Music management functions - LoadMusicStream :: proc(fileName: cstring) -> Music --- // Load music stream from file + LoadMusicStream :: proc(fileName: cstring) -> Music --- // Load music stream from file LoadMusicStreamFromMemory :: proc(fileType: cstring, data: rawptr, dataSize: c.int) -> Music --- // Load music stream from data - IsMusicValid :: proc(music: Music) -> bool --- // Checks if a music stream is valid (context and buffers initialized) - UnloadMusicStream :: proc(music: Music) --- // Unload music stream - PlayMusicStream :: proc(music: Music) --- // Start music playing - IsMusicStreamPlaying :: proc(music: Music) -> bool --- // Check if music is playing - UpdateMusicStream :: proc(music: Music) --- // Updates buffers for music streaming - StopMusicStream :: proc(music: Music) --- // Stop music playing - PauseMusicStream :: proc(music: Music) --- // Pause music playing - ResumeMusicStream :: proc(music: Music) --- // Resume playing paused music - SeekMusicStream :: proc(music: Music, position: f32) --- // Seek music to a position (in seconds) - SetMusicVolume :: proc(music: Music, volume: f32) --- // Set volume for music (1.0 is max level) - SetMusicPitch :: proc(music: Music, pitch: f32) --- // Set pitch for a music (1.0 is base level) - SetMusicPan :: proc(music: Music, pan: f32) --- // Set pan for a music (0.5 is center) - GetMusicTimeLength :: proc(music: Music) -> f32 --- // Get music time length (in seconds) - GetMusicTimePlayed :: proc(music: Music) -> f32 --- // Get current music time played (in seconds) + IsMusicValid :: proc(music: Music) -> bool --- // Checks if a music stream is valid (context and buffers initialized) + UnloadMusicStream :: proc(music: Music) --- // Unload music stream + PlayMusicStream :: proc(music: Music) --- // Start music playing + IsMusicStreamPlaying :: proc(music: Music) -> bool --- // Check if music is playing + UpdateMusicStream :: proc(music: Music) --- // Updates buffers for music streaming + StopMusicStream :: proc(music: Music) --- // Stop music playing + PauseMusicStream :: proc(music: Music) --- // Pause music playing + ResumeMusicStream :: proc(music: Music) --- // Resume playing paused music + SeekMusicStream :: proc(music: Music, position: f32) --- // Seek music to a position (in seconds) + SetMusicVolume :: proc(music: Music, volume: f32) --- // Set volume for music (1.0 is max level) + SetMusicPitch :: proc(music: Music, pitch: f32) --- // Set pitch for a music (1.0 is base level) + SetMusicPan :: proc(music: Music, pan: f32) --- // Set pan for a music (0.5 is center) + GetMusicTimeLength :: proc(music: Music) -> f32 --- // Get music time length (in seconds) + GetMusicTimePlayed :: proc(music: Music) -> f32 --- // Get current music time played (in seconds) // AudioStream management functions - LoadAudioStream :: proc(sampleRate, sampleSize: c.uint, channels: c.uint) -> AudioStream --- // Load audio stream (to stream raw audio pcm data) - IsAudioStreamValid :: proc(stream: AudioStream) -> bool --- // Checks if an audio stream is valid (buffers initialized) - UnloadAudioStream :: proc(stream: AudioStream) --- // Unload audio stream and free memory - UpdateAudioStream :: proc(stream: AudioStream, data: rawptr, frameCount: c.int) --- // Update audio stream buffers with data - IsAudioStreamProcessed :: proc(stream: AudioStream) -> bool --- // Check if any audio stream buffers requires refill - PlayAudioStream :: proc(stream: AudioStream) --- // Play audio stream - PauseAudioStream :: proc(stream: AudioStream) --- // Pause audio stream - ResumeAudioStream :: proc(stream: AudioStream) --- // Resume audio stream - IsAudioStreamPlaying :: proc(stream: AudioStream) -> bool --- // Check if audio stream is playing - StopAudioStream :: proc(stream: AudioStream) --- // Stop audio stream - SetAudioStreamVolume :: proc(stream: AudioStream, volume: f32) --- // Set volume for audio stream (1.0 is max level) - SetAudioStreamPitch :: proc(stream: AudioStream, pitch: f32) --- // Set pitch for audio stream (1.0 is base level) - SetAudioStreamPan :: proc(stream: AudioStream, pan: f32) --- // Set pan for audio stream (0.5 is centered) - SetAudioStreamBufferSizeDefault :: proc(size: c.int) --- // Default size for new audio streams - SetAudioStreamCallback :: proc(stream: AudioStream, callback: AudioCallback) --- // Audio thread callback to request new data + LoadAudioStream :: proc(sampleRate, sampleSize: c.uint, channels: c.uint) -> AudioStream --- // Load audio stream (to stream raw audio pcm data) + IsAudioStreamValid :: proc(stream: AudioStream) -> bool --- // Checks if an audio stream is valid (buffers initialized) + UnloadAudioStream :: proc(stream: AudioStream) --- // Unload audio stream and free memory + UpdateAudioStream :: proc(stream: AudioStream, data: rawptr, frameCount: c.int) --- // Update audio stream buffers with data + IsAudioStreamProcessed :: proc(stream: AudioStream) -> bool --- // Check if any audio stream buffers requires refill + PlayAudioStream :: proc(stream: AudioStream) --- // Play audio stream + PauseAudioStream :: proc(stream: AudioStream) --- // Pause audio stream + ResumeAudioStream :: proc(stream: AudioStream) --- // Resume audio stream + IsAudioStreamPlaying :: proc(stream: AudioStream) -> bool --- // Check if audio stream is playing + StopAudioStream :: proc(stream: AudioStream) --- // Stop audio stream + SetAudioStreamVolume :: proc(stream: AudioStream, volume: f32) --- // Set volume for audio stream (1.0 is max level) + SetAudioStreamPitch :: proc(stream: AudioStream, pitch: f32) --- // Set pitch for audio stream (1.0 is base level) + SetAudioStreamPan :: proc(stream: AudioStream, pan: f32) --- // Set pan for audio stream (0.5 is centered) + SetAudioStreamBufferSizeDefault :: proc(size: c.int) --- // Default size for new audio streams + SetAudioStreamCallback :: proc(stream: AudioStream, callback: AudioCallback) --- // Audio thread callback to request new data AttachAudioStreamProcessor :: proc(stream: AudioStream, processor: AudioCallback) --- // Attach audio stream processor to stream, receives the samples as 'float' DetachAudioStreamProcessor :: proc(stream: AudioStream, processor: AudioCallback) --- // Detach audio stream processor from stream @@ -1663,7 +1697,7 @@ foreign lib { // Check if a gesture have been detected IsGestureDetected :: proc "c" (gesture: Gesture) -> bool { - @(default_calling_convention = "c") + @(default_calling_convention="c") foreign lib { IsGestureDetected :: proc "c" (gesture: Gestures) -> bool --- } @@ -1673,36 +1707,36 @@ IsGestureDetected :: proc "c" (gesture: Gesture) -> bool { // Text formatting with variables (sprintf style) TextFormat :: proc(text: cstring, args: ..any) -> cstring { - @(static) buffers: [MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH]byte - @(static) index: u32 - + @static buffers: [MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH]byte + @static index: u32 + buffer := buffers[index][:] mem.zero_slice(buffer) - - index = (index + 1) % MAX_TEXTFORMAT_BUFFERS - - str := fmt.bprintf(buffer[:len(buffer) - 1], string(text), ..args) + + index = (index+1)%MAX_TEXTFORMAT_BUFFERS + + str := fmt.bprintf(buffer[:len(buffer)-1], string(text), ..args) buffer[len(str)] = 0 - + return cstring(raw_data(buffer)) } // Text formatting with variables (sprintf style) and allocates (must be freed with 'MemFree') TextFormatAlloc :: proc(text: cstring, args: ..any) -> cstring { - return fmt.caprintf(string(text), ..args, allocator = MemAllocator()) + return fmt.caprintf(string(text), ..args, allocator=MemAllocator()) } // Internal memory free -MemFree :: proc { +MemFree :: proc{ MemFreePtr, MemFreeCstring, } -@(default_calling_convention = "c") +@(default_calling_convention="c") foreign lib { - @(link_name = "MemFree") + @(link_name="MemFree") MemFreePtr :: proc(ptr: rawptr) --- } @@ -1715,17 +1749,9 @@ MemAllocator :: proc "contextless" () -> mem.Allocator { return mem.Allocator{MemAllocatorProc, nil} } -MemAllocatorProc :: proc( - allocator_data: rawptr, - mode: mem.Allocator_Mode, - size, alignment: int, - old_memory: rawptr, - old_size: int, - location := #caller_location, -) -> ( - data: []byte, - err: mem.Allocator_Error, -) { +MemAllocatorProc :: proc(allocator_data: rawptr, mode: mem.Allocator_Mode, + size, alignment: int, + old_memory: rawptr, old_size: int, location := #caller_location) -> (data: []byte, err: mem.Allocator_Error) { switch mode { case .Alloc, .Alloc_Non_Zeroed: ptr := MemAlloc(c.uint(size)) @@ -1738,7 +1764,7 @@ MemAllocatorProc :: proc( case .Free: MemFree(old_memory) return nil, nil - + case .Resize, .Resize_Non_Zeroed: ptr := MemRealloc(old_memory, c.uint(size)) if ptr == nil { @@ -1747,23 +1773,23 @@ MemAllocatorProc :: proc( } data = mem.byte_slice(ptr, size) return - + case .Free_All, .Query_Features, .Query_Info: return nil, .Mode_Not_Implemented - } + } return nil, .Mode_Not_Implemented } // RayLib 5.5 renamed Is*Ready to Is*Valid. // See: https://github.com/raysan5/raylib/commit/8cbf34ddc495e2bca42245f786915c27210b0507 -IsImageReady :: IsImageValid -IsTextureReady :: IsTextureValid +IsImageReady :: IsImageValid +IsTextureReady :: IsTextureValid IsRenderTextureReady :: IsRenderTextureValid -IsFontReady :: IsFontValid -IsModelReady :: IsModelValid -IsMaterialReady :: IsMaterialValid -IsWaveReady :: IsWaveValid -IsSoundReady :: IsSoundValid -IsMusicReady :: IsMusicValid -IsAudioStreamReady :: IsAudioStreamValid -IsShaderReady :: IsShaderValid +IsFontReady :: IsFontValid +IsModelReady :: IsModelValid +IsMaterialReady :: IsMaterialValid +IsWaveReady :: IsWaveValid +IsSoundReady :: IsSoundValid +IsMusicReady :: IsMusicValid +IsAudioStreamReady :: IsAudioStreamValid +IsShaderReady :: IsShaderValid diff --git a/libs/raylib/raymath.odin b/libs/raylib/raymath.odin index c66498e..9874d50 100644 --- a/libs/raylib/raymath.odin +++ b/libs/raylib/raymath.odin @@ -523,7 +523,7 @@ Vector3Unproject :: proc "c" (source: Vector3, projection: Matrix, view: Matrix) quat: Quaternion quat.x = source.x - quat.y = source.z + quat.y = source.y quat.z = source.z quat.w = 1 @@ -831,8 +831,8 @@ fmaxf :: proc "contextless" (x, y: f32) -> f32 { return x } - if math.signbit(x) != math.signbit(y) { - return y if math.signbit(x) else x + if math.sign_bit(x) != math.sign_bit(y) { + return y if math.sign_bit(x) else x } return y if x < y else x diff --git a/libs/raylib/rlgl/rlgl.odin b/libs/raylib/rlgl/rlgl.odin index 16d8b9f..6336be2 100644 --- a/libs/raylib/rlgl/rlgl.odin +++ b/libs/raylib/rlgl/rlgl.odin @@ -107,8 +107,8 @@ package rlgl -import rl "../." import "core:c" +import rl "../." VERSION :: "5.0" @@ -132,17 +132,17 @@ when ODIN_OS == .Windows { foreign import lib "system:raylib" } -GRAPHICS_API_OPENGL_11 :: false -GRAPHICS_API_OPENGL_21 :: true -GRAPHICS_API_OPENGL_33 :: GRAPHICS_API_OPENGL_21 // default currently +GRAPHICS_API_OPENGL_11 :: false +GRAPHICS_API_OPENGL_21 :: true +GRAPHICS_API_OPENGL_33 :: GRAPHICS_API_OPENGL_21 // default currently GRAPHICS_API_OPENGL_ES2 :: false -GRAPHICS_API_OPENGL_43 :: false +GRAPHICS_API_OPENGL_43 :: false GRAPHICS_API_OPENGL_ES3 :: false when GRAPHICS_API_OPENGL_ES3 { GRAPHICS_API_OPENGL_ES2 :: true } - + when !GRAPHICS_API_OPENGL_ES2 { // This is the maximum amount of elements (quads) per batch // NOTE: Be careful with text, every letter maps to a quad @@ -154,100 +154,100 @@ when !GRAPHICS_API_OPENGL_ES2 { DEFAULT_BATCH_BUFFER_ELEMENTS :: 2048 } -DEFAULT_BATCH_BUFFERS :: 1 // Default number of batch buffers (multi-buffering) -DEFAULT_BATCH_DRAWCALLS :: 256 // Default number of batch draw calls (by state changes: mode, texture) -DEFAULT_BATCH_MAX_TEXTURE_UNITS :: 4 // Maximum number of additional textures that can be activated on batch drawing (SetShaderValueTexture()) +DEFAULT_BATCH_BUFFERS :: 1 // Default number of batch buffers (multi-buffering) +DEFAULT_BATCH_DRAWCALLS :: 256 // Default number of batch draw calls (by state changes: mode, texture) +DEFAULT_BATCH_MAX_TEXTURE_UNITS :: 4 // Maximum number of additional textures that can be activated on batch drawing (SetShaderValueTexture()) // Internal Matrix stack -MAX_MATRIX_STACK_SIZE :: 32 // Maximum size of Matrix stack +MAX_MATRIX_STACK_SIZE :: 32 // Maximum size of Matrix stack // Shader limits -MAX_SHADER_LOCATIONS :: 32 // Maximum number of shader locations supported +MAX_SHADER_LOCATIONS :: 32 // Maximum number of shader locations supported // Projection matrix culling -CULL_DISTANCE_NEAR :: 0.01 // Default near cull distance -CULL_DISTANCE_FAR :: 1000.0 // Default far cull distance +CULL_DISTANCE_NEAR :: 0.01 // Default near cull distance +CULL_DISTANCE_FAR :: 1000.0 // Default far cull distance // Texture parameters (equivalent to OpenGL defines) -TEXTURE_WRAP_S :: 0x2802 // GL_TEXTURE_WRAP_S -TEXTURE_WRAP_T :: 0x2803 // GL_TEXTURE_WRAP_T -TEXTURE_MAG_FILTER :: 0x2800 // GL_TEXTURE_MAG_FILTER -TEXTURE_MIN_FILTER :: 0x2801 // GL_TEXTURE_MIN_FILTER +TEXTURE_WRAP_S :: 0x2802 // GL_TEXTURE_WRAP_S +TEXTURE_WRAP_T :: 0x2803 // GL_TEXTURE_WRAP_T +TEXTURE_MAG_FILTER :: 0x2800 // GL_TEXTURE_MAG_FILTER +TEXTURE_MIN_FILTER :: 0x2801 // GL_TEXTURE_MIN_FILTER -TEXTURE_FILTER_NEAREST :: 0x2600 // GL_NEAREST -TEXTURE_FILTER_LINEAR :: 0x2601 // GL_LINEAR -TEXTURE_FILTER_MIP_NEAREST :: 0x2700 // GL_NEAREST_MIPMAP_NEAREST -TEXTURE_FILTER_NEAREST_MIP_LINEAR :: 0x2702 // GL_NEAREST_MIPMAP_LINEAR -TEXTURE_FILTER_LINEAR_MIP_NEAREST :: 0x2701 // GL_LINEAR_MIPMAP_NEAREST -TEXTURE_FILTER_MIP_LINEAR :: 0x2703 // GL_LINEAR_MIPMAP_LINEAR -TEXTURE_FILTER_ANISOTROPIC :: 0x3000 // Anisotropic filter (custom identifier) +TEXTURE_FILTER_NEAREST :: 0x2600 // GL_NEAREST +TEXTURE_FILTER_LINEAR :: 0x2601 // GL_LINEAR +TEXTURE_FILTER_MIP_NEAREST :: 0x2700 // GL_NEAREST_MIPMAP_NEAREST +TEXTURE_FILTER_NEAREST_MIP_LINEAR :: 0x2702 // GL_NEAREST_MIPMAP_LINEAR +TEXTURE_FILTER_LINEAR_MIP_NEAREST :: 0x2701 // GL_LINEAR_MIPMAP_NEAREST +TEXTURE_FILTER_MIP_LINEAR :: 0x2703 // GL_LINEAR_MIPMAP_LINEAR +TEXTURE_FILTER_ANISOTROPIC :: 0x3000 // Anisotropic filter (custom identifier) -TEXTURE_WRAP_REPEAT :: 0x2901 // GL_REPEAT -TEXTURE_WRAP_CLAMP :: 0x812F // GL_CLAMP_TO_EDGE -TEXTURE_WRAP_MIRROR_REPEAT :: 0x8370 // GL_MIRRORED_REPEAT -TEXTURE_WRAP_MIRROR_CLAMP :: 0x8742 // GL_MIRROR_CLAMP_EXT +TEXTURE_WRAP_REPEAT :: 0x2901 // GL_REPEAT +TEXTURE_WRAP_CLAMP :: 0x812F // GL_CLAMP_TO_EDGE +TEXTURE_WRAP_MIRROR_REPEAT :: 0x8370 // GL_MIRRORED_REPEAT +TEXTURE_WRAP_MIRROR_CLAMP :: 0x8742 // GL_MIRROR_CLAMP_EXT // Matrix modes (equivalent to OpenGL) -MODELVIEW :: 0x1700 // GL_MODELVIEW -PROJECTION :: 0x1701 // GL_PROJECTION -TEXTURE :: 0x1702 // GL_TEXTURE +MODELVIEW :: 0x1700 // GL_MODELVIEW +PROJECTION :: 0x1701 // GL_PROJECTION +TEXTURE :: 0x1702 // GL_TEXTURE // Primitive assembly draw modes -LINES :: 0x0001 // GL_LINES -TRIANGLES :: 0x0004 // GL_TRIANGLES -QUADS :: 0x0007 // GL_QUADS +LINES :: 0x0001 // GL_LINES +TRIANGLES :: 0x0004 // GL_TRIANGLES +QUADS :: 0x0007 // GL_QUADS // GL equivalent data types -UNSIGNED_BYTE :: 0x1401 // GL_UNSIGNED_BYTE -FLOAT :: 0x1406 // GL_FLOAT +UNSIGNED_BYTE :: 0x1401 // GL_UNSIGNED_BYTE +FLOAT :: 0x1406 // GL_FLOAT // Buffer usage hint -STREAM_DRAW :: 0x88E0 // GL_STREAM_DRAW -STREAM_READ :: 0x88E1 // GL_STREAM_READ -STREAM_COPY :: 0x88E2 // GL_STREAM_COPY -STATIC_DRAW :: 0x88E4 // GL_STATIC_DRAW -STATIC_READ :: 0x88E5 // GL_STATIC_READ -STATIC_COPY :: 0x88E6 // GL_STATIC_COPY -DYNAMIC_DRAW :: 0x88E8 // GL_DYNAMIC_DRAW -DYNAMIC_READ :: 0x88E9 // GL_DYNAMIC_READ -DYNAMIC_COPY :: 0x88EA // GL_DYNAMIC_COPY +STREAM_DRAW :: 0x88E0 // GL_STREAM_DRAW +STREAM_READ :: 0x88E1 // GL_STREAM_READ +STREAM_COPY :: 0x88E2 // GL_STREAM_COPY +STATIC_DRAW :: 0x88E4 // GL_STATIC_DRAW +STATIC_READ :: 0x88E5 // GL_STATIC_READ +STATIC_COPY :: 0x88E6 // GL_STATIC_COPY +DYNAMIC_DRAW :: 0x88E8 // GL_DYNAMIC_DRAW +DYNAMIC_READ :: 0x88E9 // GL_DYNAMIC_READ +DYNAMIC_COPY :: 0x88EA // GL_DYNAMIC_COPY // GL Shader type -FRAGMENT_SHADER :: 0x8B30 // GL_FRAGMENT_SHADER -VERTEX_SHADER :: 0x8B31 // GL_VERTEX_SHADER -COMPUTE_SHADER :: 0x91B9 // GL_COMPUTE_SHADER +FRAGMENT_SHADER :: 0x8B30 // GL_FRAGMENT_SHADER +VERTEX_SHADER :: 0x8B31 // GL_VERTEX_SHADER +COMPUTE_SHADER :: 0x91B9 // GL_COMPUTE_SHADER // GL blending factors -ZERO :: 0 // GL_ZERO -ONE :: 1 // GL_ONE -SRC_COLOR :: 0x0300 // GL_SRC_COLOR -ONE_MINUS_SRC_COLOR :: 0x0301 // GL_ONE_MINUS_SRC_COLOR -SRC_ALPHA :: 0x0302 // GL_SRC_ALPHA -ONE_MINUS_SRC_ALPHA :: 0x0303 // GL_ONE_MINUS_SRC_ALPHA -DST_ALPHA :: 0x0304 // GL_DST_ALPHA -ONE_MINUS_DST_ALPHA :: 0x0305 // GL_ONE_MINUS_DST_ALPHA -DST_COLOR :: 0x0306 // GL_DST_COLOR -ONE_MINUS_DST_COLOR :: 0x0307 // GL_ONE_MINUS_DST_COLOR -SRC_ALPHA_SATURATE :: 0x0308 // GL_SRC_ALPHA_SATURATE -CONSTANT_COLOR :: 0x8001 // GL_CONSTANT_COLOR -ONE_MINUS_CONSTANT_COLOR :: 0x8002 // GL_ONE_MINUS_CONSTANT_COLOR -CONSTANT_ALPHA :: 0x8003 // GL_CONSTANT_ALPHA -ONE_MINUS_CONSTANT_ALPHA :: 0x8004 // GL_ONE_MINUS_CONSTANT_ALPHA +ZERO :: 0 // GL_ZERO +ONE :: 1 // GL_ONE +SRC_COLOR :: 0x0300 // GL_SRC_COLOR +ONE_MINUS_SRC_COLOR :: 0x0301 // GL_ONE_MINUS_SRC_COLOR +SRC_ALPHA :: 0x0302 // GL_SRC_ALPHA +ONE_MINUS_SRC_ALPHA :: 0x0303 // GL_ONE_MINUS_SRC_ALPHA +DST_ALPHA :: 0x0304 // GL_DST_ALPHA +ONE_MINUS_DST_ALPHA :: 0x0305 // GL_ONE_MINUS_DST_ALPHA +DST_COLOR :: 0x0306 // GL_DST_COLOR +ONE_MINUS_DST_COLOR :: 0x0307 // GL_ONE_MINUS_DST_COLOR +SRC_ALPHA_SATURATE :: 0x0308 // GL_SRC_ALPHA_SATURATE +CONSTANT_COLOR :: 0x8001 // GL_CONSTANT_COLOR +ONE_MINUS_CONSTANT_COLOR :: 0x8002 // GL_ONE_MINUS_CONSTANT_COLOR +CONSTANT_ALPHA :: 0x8003 // GL_CONSTANT_ALPHA +ONE_MINUS_CONSTANT_ALPHA :: 0x8004 // GL_ONE_MINUS_CONSTANT_ALPHA // GL blending functions/equations -FUNC_ADD :: 0x8006 // GL_FUNC_ADD -MIN :: 0x8007 // GL_MIN -MAX :: 0x8008 // GL_MAX -FUNC_SUBTRACT :: 0x800A // GL_FUNC_SUBTRACT -FUNC_REVERSE_SUBTRACT :: 0x800B // GL_FUNC_REVERSE_SUBTRACT -BLEND_EQUATION :: 0x8009 // GL_BLEND_EQUATION -BLEND_EQUATION_RGB :: 0x8009 // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) -BLEND_EQUATION_ALPHA :: 0x883D // GL_BLEND_EQUATION_ALPHA -BLEND_DST_RGB :: 0x80C8 // GL_BLEND_DST_RGB -BLEND_SRC_RGB :: 0x80C9 // GL_BLEND_SRC_RGB -BLEND_DST_ALPHA :: 0x80CA // GL_BLEND_DST_ALPHA -BLEND_SRC_ALPHA :: 0x80CB // GL_BLEND_SRC_ALPHA -BLEND_COLOR :: 0x8005 // GL_BLEND_COLOR +FUNC_ADD :: 0x8006 // GL_FUNC_ADD +MIN :: 0x8007 // GL_MIN +MAX :: 0x8008 // GL_MAX +FUNC_SUBTRACT :: 0x800A // GL_FUNC_SUBTRACT +FUNC_REVERSE_SUBTRACT :: 0x800B // GL_FUNC_REVERSE_SUBTRACT +BLEND_EQUATION :: 0x8009 // GL_BLEND_EQUATION +BLEND_EQUATION_RGB :: 0x8009 // GL_BLEND_EQUATION_RGB // (Same as BLEND_EQUATION) +BLEND_EQUATION_ALPHA :: 0x883D // GL_BLEND_EQUATION_ALPHA +BLEND_DST_RGB :: 0x80C8 // GL_BLEND_DST_RGB +BLEND_SRC_RGB :: 0x80C9 // GL_BLEND_SRC_RGB +BLEND_DST_ALPHA :: 0x80CA // GL_BLEND_DST_ALPHA +BLEND_SRC_ALPHA :: 0x80CB // GL_BLEND_SRC_ALPHA +BLEND_COLOR :: 0x8005 // GL_BLEND_COLOR //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -258,13 +258,14 @@ VertexBufferIndexType :: c.ushort when GRAPHICS_API_OPENGL_ES2 else c.uint // Dynamic vertex buffers (position + texcoords + colors + indices arrays) VertexBuffer :: struct { - elementCount: c.int, // Number of elements in the buffer (QUADS) - vertices: [^]f32, // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) - texcoords: [^]f32, // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) - colors: [^]u8, // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) - indices: [^]VertexBufferIndexType, // Vertex indices (in case vertex data comes indexed) (6 indices per quad) - vaoId: c.uint, // OpenGL Vertex Array Object id - vboId: [4]c.uint, // OpenGL Vertex Buffer Objects id (4 types of vertex data) + elementCount: c.int, // Number of elements in the buffer (QUADS) + + vertices: [^]f32, // Vertex position (XYZ - 3 components per vertex) (shader-location = 0) + texcoords: [^]f32, // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1) + colors: [^]u8, // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3) + indices: [^]VertexBufferIndexType, // Vertex indices (in case vertex data comes indexed) (6 indices per quad) + vaoId: c.uint, // OpenGL Vertex Array Object id + vboId: [4]c.uint, // OpenGL Vertex Buffer Objects id (4 types of vertex data) } // Draw call type @@ -272,30 +273,31 @@ VertexBuffer :: struct { // 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) DrawCall :: struct { - mode: c.int, // Drawing mode: LINES, TRIANGLES, QUADS - vertexCount: c.int, // Number of vertex of the draw - vertexAlignment: c.int, // Number of vertex required for index alignment (LINES, TRIANGLES) - textureId: c.uint, // Texture id to be used on the draw -> Use to create new draw call if changes + mode: c.int, // Drawing mode: LINES, TRIANGLES, QUADS + vertexCount: c.int, // Number of vertex of the draw + vertexAlignment: c.int, // Number of vertex required for index alignment (LINES, TRIANGLES) + textureId: c.uint, // Texture id to be used on the draw -> Use to create new draw call if changes } // RenderBatch type RenderBatch :: struct { - bufferCount: c.int, // Number of vertex buffers (multi-buffering support) - currentBuffer: c.int, // Current buffer tracking in case of multi-buffering + bufferCount: c.int, // Number of vertex buffers (multi-buffering support) + currentBuffer: c.int, // Current buffer tracking in case of multi-buffering vertexBuffer: [^]VertexBuffer, // Dynamic buffer(s) for vertex data - draws: [^]DrawCall, // Draw calls array, depends on textureId - drawCounter: c.int, // Draw calls counter - currentDepth: f32, // Current depth value for next draw + + draws: [^]DrawCall, // Draw calls array, depends on textureId + drawCounter: c.int, // Draw calls counter + currentDepth: f32, // Current depth value for next draw } // OpenGL version GlVersion :: enum c.int { - OPENGL_11 = 1, // OpenGL 1.1 - OPENGL_21, // OpenGL 2.1 (GLSL 120) - OPENGL_33, // OpenGL 3.3 (GLSL 330) - OPENGL_43, // OpenGL 4.3 (using GLSL 330) - OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) - OPENGL_ES_30, // OpenGL ES 3.0 (GLSL 300 es) + OPENGL_11 = 1, // OpenGL 1.1 + OPENGL_21, // OpenGL 2.1 (GLSL 120) + OPENGL_33, // OpenGL 3.3 (GLSL 330) + OPENGL_43, // OpenGL 4.3 (using GLSL 330) + OPENGL_ES_20, // OpenGL ES 2.0 (GLSL 100) + OPENGL_ES_30, // OpenGL ES 3.0 (GLSL 300 es) } PixelFormat :: rl.PixelFormat @@ -306,25 +308,25 @@ ShaderUniformDataType :: rl.ShaderUniformDataType // Shader attribute data types ShaderAttributeDataType :: enum c.int { - FLOAT = 0, // Shader attribute type: float - VEC2, // Shader attribute type: vec2 (2 float) - VEC3, // Shader attribute type: vec3 (3 float) - VEC4, // Shader attribute type: vec4 (4 float) + FLOAT = 0, // Shader attribute type: float + VEC2, // Shader attribute type: vec2 (2 float) + VEC3, // Shader attribute type: vec3 (3 float) + VEC4, // Shader attribute type: vec4 (4 float) } // Framebuffer attachment type // NOTE: By default up to 8 color channels defined, but it can be more FramebufferAttachType :: enum c.int { - COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 - COLOR_CHANNEL1 = 1, // Framebuffer attachment type: color 1 - COLOR_CHANNEL2 = 2, // Framebuffer attachment type: color 2 - COLOR_CHANNEL3 = 3, // Framebuffer attachment type: color 3 - COLOR_CHANNEL4 = 4, // Framebuffer attachment type: color 4 - COLOR_CHANNEL5 = 5, // Framebuffer attachment type: color 5 - COLOR_CHANNEL6 = 6, // Framebuffer attachment type: color 6 - COLOR_CHANNEL7 = 7, // Framebuffer attachment type: color 7 - DEPTH = 100, // Framebuffer attachment type: depth - STENCIL = 200, // Framebuffer attachment type: stencil + COLOR_CHANNEL0 = 0, // Framebuffer attachment type: color 0 + COLOR_CHANNEL1 = 1, // Framebuffer attachment type: color 1 + COLOR_CHANNEL2 = 2, // Framebuffer attachment type: color 2 + COLOR_CHANNEL3 = 3, // Framebuffer attachment type: color 3 + COLOR_CHANNEL4 = 4, // Framebuffer attachment type: color 4 + COLOR_CHANNEL5 = 5, // Framebuffer attachment type: color 5 + COLOR_CHANNEL6 = 6, // Framebuffer attachment type: color 6 + COLOR_CHANNEL7 = 7, // Framebuffer attachment type: color 7 + DEPTH = 100, // Framebuffer attachment type: depth + STENCIL = 200, // Framebuffer attachment type: stencil } // Framebuffer texture attachment type @@ -335,8 +337,8 @@ FramebufferAttachTextureType :: enum c.int { CUBEMAP_NEGATIVE_Y = 3, // Framebuffer texture attachment type: cubemap, -Y side CUBEMAP_POSITIVE_Z = 4, // Framebuffer texture attachment type: cubemap, +Z side CUBEMAP_NEGATIVE_Z = 5, // Framebuffer texture attachment type: cubemap, -Z side - TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d - RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer + TEXTURE2D = 100, // Framebuffer texture attachment type: texture2d + RENDERBUFFER = 200, // Framebuffer texture attachment type: renderbuffer } CullMode :: enum c.int { @@ -346,37 +348,39 @@ CullMode :: enum c.int { Matrix :: rl.Matrix -@(default_calling_convention = "c", link_prefix = "rl") +@(default_calling_convention="c", link_prefix="rl") foreign lib { //------------------------------------------------------------------------------------ // Functions Declaration - Matrix operations //------------------------------------------------------------------------------------ - MatrixMode :: proc(mode: c.int) --- // Choose the current matrix to be transformed - PushMatrix :: proc() --- // Push the current matrix to stack - PopMatrix :: proc() --- // Pop lattest inserted matrix from stack - LoadIdentity :: proc() --- // Reset current matrix to identity matrix - Translatef :: proc(x, y, z: f32) --- // Multiply the current matrix by a translation matrix - Rotatef :: proc(angleDeg: f32, x, y, z: f32) --- // Multiply the current matrix by a rotation matrix - Scalef :: proc(x, y, z: f32) --- // Multiply the current matrix by a scaling matrix - MultMatrixf :: proc(matf: [^]f32) --- // Multiply the current matrix by another matrix - Frustum :: proc(left, right, bottom, top, znear, zfar: f64) --- - Ortho :: proc(left, right, bottom, top, znear, zfar: f64) --- - Viewport :: proc(x, y, width, height: c.int) --- // Set the viewport area - SetClipPlanes :: proc(nearPlane, farPlane: f64) --- // Set clip planes + MatrixMode :: proc(mode: c.int) --- // Choose the current matrix to be transformed + PushMatrix :: proc() --- // Push the current matrix to stack + PopMatrix :: proc() --- // Pop lattest inserted matrix from stack + LoadIdentity :: proc() --- // Reset current matrix to identity matrix + Translatef :: proc(x, y, z: f32) --- // Multiply the current matrix by a translation matrix + Rotatef :: proc(angleDeg: f32, x, y, z: f32) --- // Multiply the current matrix by a rotation matrix + Scalef :: proc(x, y, z: f32) --- // Multiply the current matrix by a scaling matrix + MultMatrixf :: proc(matf: [^]f32) --- // Multiply the current matrix by another matrix + Frustum :: proc(left, right, bottom, top, znear, zfar: f64) --- + Ortho :: proc(left, right, bottom, top, znear, zfar: f64) --- + Viewport :: proc(x, y, width, height: c.int) --- // Set the viewport area + SetClipPlanes :: proc(near, far: f64) --- // Set clip planes distances + GetCullDistanceNear :: proc() -> f64 --- // Get cull plane distance near + GetCullDistanceFar :: proc() -> f64 --- // Get cull plane distance far //------------------------------------------------------------------------------------ // Functions Declaration - Vertex level operations //------------------------------------------------------------------------------------ - Begin :: proc(mode: c.int) --- // Initialize drawing mode (how to organize vertex) - End :: proc() --- // Finish vertex providing - Vertex2i :: proc(x, y: c.int) --- // Define one vertex (position) - 2 int - Vertex2f :: proc(x, y: f32) --- // Define one vertex (position) - 2 f32 - Vertex3f :: proc(x, y, z: f32) --- // Define one vertex (position) - 3 f32 - TexCoord2f :: proc(x, y: f32) --- // Define one vertex (texture coordinate) - 2 f32 - Normal3f :: proc(x, y, z: f32) --- // Define one vertex (normal) - 3 f32 - Color4ub :: proc(r, g, b, a: u8) --- // Define one vertex (color) - 4 byte - Color3f :: proc(x, y, z: f32) --- // Define one vertex (color) - 3 f32 - Color4f :: proc(x, y, z, w: f32) --- // Define one vertex (color) - 4 f32 + Begin :: proc(mode: c.int) --- // Initialize drawing mode (how to organize vertex) + End :: proc() --- // Finish vertex providing + Vertex2i :: proc(x, y: c.int) --- // Define one vertex (position) - 2 int + Vertex2f :: proc(x, y: f32) --- // Define one vertex (position) - 2 f32 + Vertex3f :: proc(x, y, z: f32) --- // Define one vertex (position) - 3 f32 + TexCoord2f :: proc(x, y: f32) --- // Define one vertex (texture coordinate) - 2 f32 + Normal3f :: proc(x, y, z: f32) --- // Define one vertex (normal) - 3 f32 + Color4ub :: proc(r, g, b, a: u8) --- // Define one vertex (color) - 4 byte + Color3f :: proc(x, y, z: f32) --- // Define one vertex (color) - 3 f32 + Color4f :: proc(x, y, z, w: f32) --- // Define one vertex (color) - 4 f32 //------------------------------------------------------------------------------------ // Functions Declaration - OpenGL style functions (common to 1.1, 3.3+, ES2) @@ -385,176 +389,176 @@ foreign lib { //------------------------------------------------------------------------------------ // Vertex buffers state - EnableVertexArray :: proc(vaoId: c.uint) -> bool --- // Enable vertex array (VAO, if supported) - DisableVertexArray :: proc() --- // Disable vertex array (VAO, if supported) - EnableVertexBuffer :: proc(id: c.uint) --- // Enable vertex buffer (VBO) - DisableVertexBuffer :: proc() --- // Disable vertex buffer (VBO) - EnableVertexBufferElement :: proc(id: c.uint) --- // Enable vertex buffer element (VBO element) - DisableVertexBufferElement :: proc() --- // Disable vertex buffer element (VBO element) - EnableVertexAttribute :: proc(index: c.uint) --- // Enable vertex attribute index - DisableVertexAttribute :: proc(index: c.uint) --- // Disable vertex attribute index + EnableVertexArray :: proc(vaoId: c.uint) -> bool --- // Enable vertex array (VAO, if supported) + DisableVertexArray :: proc() --- // Disable vertex array (VAO, if supported) + EnableVertexBuffer :: proc(id: c.uint) --- // Enable vertex buffer (VBO) + DisableVertexBuffer :: proc() --- // Disable vertex buffer (VBO) + EnableVertexBufferElement :: proc(id: c.uint) --- // Enable vertex buffer element (VBO element) + DisableVertexBufferElement :: proc() --- // Disable vertex buffer element (VBO element) + EnableVertexAttribute :: proc(index: c.uint) --- // Enable vertex attribute index + DisableVertexAttribute :: proc(index: c.uint) --- // Disable vertex attribute index when GRAPHICS_API_OPENGL_11 { EnableStatePointer :: proc(vertexAttribType: c.int, buffer: rawptr) --- DisableStatePointer :: proc(vertexAttribType: c.int) --- } // Textures state - ActiveTextureSlot :: proc(slot: c.int) --- // Select and active a texture slot - EnableTexture :: proc(id: c.uint) --- // Enable texture - DisableTexture :: proc() --- // Disable texture - EnableTextureCubemap :: proc(id: c.uint) --- // Enable texture cubemap - DisableTextureCubemap :: proc() --- // Disable texture cubemap - TextureParameters :: proc(id: c.uint, param: c.int, value: c.int) --- // Set texture parameters (filter, wrap) - CubemapParameters :: proc(id: i32, param: c.int, value: c.int) --- // Set cubemap parameters (filter, wrap) + ActiveTextureSlot :: proc(slot: c.int) --- // Select and active a texture slot + EnableTexture :: proc(id: c.uint) --- // Enable texture + DisableTexture :: proc() --- // Disable texture + EnableTextureCubemap :: proc(id: c.uint) --- // Enable texture cubemap + DisableTextureCubemap :: proc() --- // Disable texture cubemap + TextureParameters :: proc(id: c.uint, param: c.int, value: c.int) --- // Set texture parameters (filter, wrap) + CubemapParameters :: proc(id: i32, param: c.int, value: c.int) --- // Set cubemap parameters (filter, wrap) // Shader state - EnableShader :: proc(id: c.uint) --- // Enable shader program - DisableShader :: proc() --- // Disable shader program + EnableShader :: proc(id: c.uint) --- // Enable shader program + DisableShader :: proc() --- // Disable shader program // Framebuffer state - EnableFramebuffer :: proc(id: c.uint) --- // Enable render texture (fbo) - DisableFramebuffer :: proc() --- // Disable render texture (fbo), return to default framebuffer - ActiveDrawBuffers :: proc(count: c.int) --- // Activate multiple draw color buffers - BlitFramebuffer :: proc(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask: c.int) --- // Blit active framebuffer to main framebuffer + EnableFramebuffer :: proc(id: c.uint) --- // Enable render texture (fbo) + DisableFramebuffer :: proc() --- // Disable render texture (fbo), return to default framebuffer + ActiveDrawBuffers :: proc(count: c.int) --- // Activate multiple draw color buffers + BlitFramebuffer :: proc(srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, bufferMask: c.int) --- // Blit active framebuffer to main framebuffer // General render state - EnableColorBlend :: proc() --- // Enable color blending - DisableColorBlend :: proc() --- // Disable color blending - EnableDepthTest :: proc() --- // Enable depth test - DisableDepthTest :: proc() --- // Disable depth test - EnableDepthMask :: proc() --- // Enable depth write - DisableDepthMask :: proc() --- // Disable depth write - EnableBackfaceCulling :: proc() --- // Enable backface culling - DisableBackfaceCulling :: proc() --- // Disable backface culling - SetCullFace :: proc(mode: CullMode) --- // Set face culling mode - EnableScissorTest :: proc() --- // Enable scissor test - DisableScissorTest :: proc() --- // Disable scissor test - Scissor :: proc(x, y, width, height: c.int) --- // Scissor test - EnableWireMode :: proc() --- // Enable wire mode - EnablePointMode :: proc() --- // Enable point mode - DisableWireMode :: proc() --- // Disable wire and point modes - SetLineWidth :: proc(width: f32) --- // Set the line drawing width - GetLineWidth :: proc() -> f32 --- // Get the line drawing width - EnableSmoothLines :: proc() --- // Enable line aliasing - DisableSmoothLines :: proc() --- // Disable line aliasing - EnableStereoRender :: proc() --- // Enable stereo rendering - DisableStereoRender :: proc() --- // Disable stereo rendering - IsStereoRenderEnabled :: proc() -> bool --- // Check if stereo render is enabled + EnableColorBlend :: proc() --- // Enable color blending + DisableColorBlend :: proc() --- // Disable color blending + EnableDepthTest :: proc() --- // Enable depth test + DisableDepthTest :: proc() --- // Disable depth test + EnableDepthMask :: proc() --- // Enable depth write + DisableDepthMask :: proc() --- // Disable depth write + EnableBackfaceCulling :: proc() --- // Enable backface culling + DisableBackfaceCulling :: proc() --- // Disable backface culling + SetCullFace :: proc(mode: CullMode) --- // Set face culling mode + EnableScissorTest :: proc() --- // Enable scissor test + DisableScissorTest :: proc() --- // Disable scissor test + Scissor :: proc(x, y, width, height: c.int) --- // Scissor test + EnableWireMode :: proc() --- // Enable wire mode + EnablePointMode :: proc() --- // Enable point mode + DisableWireMode :: proc() --- // Disable wire and point modes + SetLineWidth :: proc(width: f32) --- // Set the line drawing width + GetLineWidth :: proc() -> f32 --- // Get the line drawing width + EnableSmoothLines :: proc() --- // Enable line aliasing + DisableSmoothLines :: proc() --- // Disable line aliasing + EnableStereoRender :: proc() --- // Enable stereo rendering + DisableStereoRender :: proc() --- // Disable stereo rendering + IsStereoRenderEnabled :: proc() -> bool --- // Check if stereo render is enabled - ClearColor :: proc(r, g, b, a: u8) --- // Clear color buffer with color - ClearScreenBuffers :: proc() --- // Clear used screen buffers (color and depth) - CheckErrors :: proc() --- // Check and log OpenGL error codes - SetBlendMode :: proc(mode: c.int) --- // Set blending mode - SetBlendFactors :: proc(glSrcFactor, glDstFactor, glEquation: c.int) --- // Set blending mode factor and equation (using OpenGL factors) + ClearColor :: proc(r, g, b, a: u8) --- // Clear color buffer with color + ClearScreenBuffers :: proc() --- // Clear used screen buffers (color and depth) + CheckErrors :: proc() --- // Check and log OpenGL error codes + SetBlendMode :: proc(mode: c.int) --- // Set blending mode + SetBlendFactors :: proc(glSrcFactor, glDstFactor, glEquation: c.int) --- // Set blending mode factor and equation (using OpenGL factors) SetBlendFactorsSeparate :: proc(glSrcRGB, glDstRGB, glSrcAlpha, glDstAlpha, glEqRGB, glEqAlpha: c.int) --- // Set blending mode factors and equations separately (using OpenGL factors) //------------------------------------------------------------------------------------ // Functions Declaration - rlgl functionality //------------------------------------------------------------------------------------ // rlgl initialization functions - @(link_prefix = "rlgl") - Init :: proc(width, height: c.int) --- // Initialize rlgl (buffers, shaders, textures, states) - @(link_prefix = "rlgl") - Close :: proc() --- // De-initialize rlgl (buffers, shaders, textures) - LoadExtensions :: proc(loader: rawptr) --- // Load OpenGL extensions (loader function required) - GetVersion :: proc() -> GlVersion --- // Get current OpenGL version - SetFramebufferWidth :: proc(width: c.int) --- // Set current framebuffer width - GetFramebufferWidth :: proc() -> c.int --- // Get default framebuffer width - SetFramebufferHeight :: proc(height: c.int) --- // Set current framebuffer height - GetFramebufferHeight :: proc() -> c.int --- // Get default framebuffer height + @(link_prefix="rlgl") + Init :: proc(width, height: c.int) --- // Initialize rlgl (buffers, shaders, textures, states) + @(link_prefix="rlgl") + Close :: proc() --- // De-initialize rlgl (buffers, shaders, textures) + LoadExtensions :: proc(loader: rawptr) --- // Load OpenGL extensions (loader function required) + GetVersion :: proc() -> GlVersion --- // Get current OpenGL version + SetFramebufferWidth :: proc(width: c.int) --- // Set current framebuffer width + GetFramebufferWidth :: proc() -> c.int --- // Get default framebuffer width + SetFramebufferHeight :: proc(height: c.int) --- // Set current framebuffer height + GetFramebufferHeight :: proc() -> c.int --- // Get default framebuffer height - GetTextureIdDefault :: proc() -> c.uint --- // Get default texture id - GetShaderIdDefault :: proc() -> c.uint --- // Get default shader id + GetTextureIdDefault :: proc() -> c.uint --- // Get default texture id + GetShaderIdDefault :: proc() -> c.uint --- // Get default shader id GetShaderLocsDefault :: proc() -> [^]c.int --- // 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 - LoadRenderBatch :: proc(numBuffers, bufferElements: c.int) -> RenderBatch --- // Load a render batch system - UnloadRenderBatch :: proc(batch: RenderBatch) --- // Unload render batch system - DrawRenderBatch :: proc(batch: ^RenderBatch) --- // Draw render batch data (Update->Draw->Reset) - SetRenderBatchActive :: proc(batch: ^RenderBatch) --- // Set the active render batch for rlgl (NULL for default internal) - DrawRenderBatchActive :: proc() --- // Update and draw internal render batch - CheckRenderBatchLimit :: proc(vCount: c.int) -> c.int --- // Check internal buffer overflow for a given number of vertex + LoadRenderBatch :: proc(numBuffers, bufferElements: c.int) -> RenderBatch --- // Load a render batch system + UnloadRenderBatch :: proc(batch: RenderBatch) --- // Unload render batch system + DrawRenderBatch :: proc(batch: ^RenderBatch) --- // Draw render batch data (Update->Draw->Reset) + SetRenderBatchActive :: proc(batch: ^RenderBatch) --- // Set the active render batch for rlgl (NULL for default internal) + DrawRenderBatchActive :: proc() --- // Update and draw internal render batch + CheckRenderBatchLimit :: proc(vCount: c.int) -> c.int --- // Check internal buffer overflow for a given number of vertex SetTexture :: proc(id: c.uint) --- // Set current texture for render batch and check buffers limits //------------------------------------------------------------------------------------------------------------------------ // Vertex buffers management - LoadVertexArray :: proc() -> c.uint --- // Load vertex array (vao) if supported - LoadVertexBuffer :: proc(buffer: rawptr, size: c.int, is_dynamic: bool) -> c.uint --- // Load a vertex buffer attribute - LoadVertexBufferElement :: proc(buffer: rawptr, size: c.int, is_dynamic: bool) -> c.uint --- // Load a new attributes element buffer - UpdateVertexBuffer :: proc(bufferId: c.uint, data: rawptr, dataSize: c.int, offset: c.int) --- // Update GPU buffer with new data - UpdateVertexBufferElements :: proc(id: c.uint, data: rawptr, dataSize: c.int, offset: c.int) --- // Update vertex buffer elements with new data - UnloadVertexArray :: proc(vaoId: c.uint) --- - UnloadVertexBuffer :: proc(vboId: c.uint) --- - SetVertexAttribute :: proc(index: c.uint, compSize: c.int, type: c.int, normalized: bool, stride: c.int, pointer: rawptr) --- - SetVertexAttributeDivisor :: proc(index: c.uint, divisor: c.int) --- - SetVertexAttributeDefault :: proc(locIndex: c.int, value: rawptr, attribType: c.int, count: c.int) --- // Set vertex attribute default value - DrawVertexArray :: proc(offset: c.int, count: c.int) --- - DrawVertexArrayElements :: proc(offset: c.int, count: c.int, buffer: rawptr) --- - DrawVertexArrayInstanced :: proc(offset: c.int, count: c.int, instances: c.int) --- + LoadVertexArray :: proc() -> c.uint --- // Load vertex array (vao) if supported + LoadVertexBuffer :: proc(buffer: rawptr, size: c.int, is_dynamic: bool) -> c.uint --- // Load a vertex buffer attribute + LoadVertexBufferElement :: proc(buffer: rawptr, size: c.int, is_dynamic: bool) -> c.uint --- // Load a new attributes element buffer + UpdateVertexBuffer :: proc(bufferId: c.uint, data: rawptr, dataSize: c.int, offset: c.int) --- // Update GPU buffer with new data + UpdateVertexBufferElements :: proc(id: c.uint, data: rawptr, dataSize: c.int, offset: c.int) --- // Update vertex buffer elements with new data + UnloadVertexArray :: proc(vaoId: c.uint) --- + UnloadVertexBuffer :: proc(vboId: c.uint) --- + SetVertexAttribute :: proc(index: c.uint, compSize: c.int, type: c.int, normalized: bool, stride: c.int, offset: c.int) --- + SetVertexAttributeDivisor :: proc(index: c.uint, divisor: c.int) --- + SetVertexAttributeDefault :: proc(locIndex: c.int, value: rawptr, attribType: c.int, count: c.int) --- // Set vertex attribute default value + DrawVertexArray :: proc(offset: c.int, count: c.int) --- + DrawVertexArrayElements :: proc(offset: c.int, count: c.int, buffer: rawptr) --- + DrawVertexArrayInstanced :: proc(offset: c.int, count: c.int, instances: c.int) --- DrawVertexArrayElementsInstanced :: proc(offset: c.int, count: c.int, buffer: rawptr, instances: c.int) --- // Textures management - LoadTexture :: proc(data: rawptr, width, height: c.int, format: c.int, mipmapCount: c.int) -> c.uint --- // Load texture in GPU - LoadTextureDepth :: proc(width, height: c.int, useRenderBuffer: bool) -> c.uint --- // Load depth texture/renderbuffer (to be attached to fbo) - LoadTextureCubemap :: proc(data: rawptr, size: c.int, format: c.int) -> c.uint --- // Load texture cubemap - UpdateTexture :: proc(id: c.uint, offsetX, offsetY: c.int, width, height: c.int, format: c.int, data: rawptr) --- // Update GPU texture with new data - GetGlTextureFormats :: proc(format: c.int, glInternalFormat, glFormat, glType: ^c.uint) --- // Get OpenGL internal formats - GetPixelFormatName :: proc(format: c.uint) -> cstring --- // Get name string for pixel format - UnloadTexture :: proc(id: c.uint) --- // Unload texture from GPU memory - GenTextureMipmaps :: proc(id: c.uint, width, height: c.int, format: c.int, mipmaps: ^c.int) --- // Generate mipmap data for selected texture - ReadTexturePixels :: proc(id: c.uint, width, height: c.int, format: c.int) -> rawptr --- // Read texture pixel data - ReadScreenPixels :: proc(width, height: c.int) -> [^]byte --- // Read screen pixel data (color buffer) + LoadTexture :: proc(data: rawptr, width, height: c.int, format: c.int, mipmapCount: c.int) -> c.uint --- // Load texture in GPU + LoadTextureDepth :: proc(width, height: c.int, useRenderBuffer: bool) -> c.uint --- // Load depth texture/renderbuffer (to be attached to fbo) + LoadTextureCubemap :: proc(data: rawptr, size: c.int, format: c.int) -> c.uint --- // Load texture cubemap + UpdateTexture :: proc(id: c.uint, offsetX, offsetY: c.int, width, height: c.int, format: c.int, data: rawptr) --- // Update GPU texture with new data + GetGlTextureFormats :: proc(format: c.int, glInternalFormat, glFormat, glType: ^c.uint) --- // Get OpenGL internal formats + GetPixelFormatName :: proc(format: c.uint) -> cstring --- // Get name string for pixel format + UnloadTexture :: proc(id: c.uint) --- // Unload texture from GPU memory + GenTextureMipmaps :: proc(id: c.uint, width, height: c.int, format: c.int, mipmaps: ^c.int) --- // Generate mipmap data for selected texture + ReadTexturePixels :: proc(id: c.uint, width, height: c.int, format: c.int) -> rawptr --- // Read texture pixel data + ReadScreenPixels :: proc(width, height: c.int) -> [^]byte --- // Read screen pixel data (color buffer) // Framebuffer management (fbo) - LoadFramebuffer :: proc(width, height: c.int) -> c.uint --- // Load an empty framebuffer - FramebufferAttach :: proc(fboId, texId: c.uint, attachType: c.int, texType: c.int, mipLevel: c.int) --- // Attach texture/renderbuffer to a framebuffer - FramebufferComplete :: proc(id: c.uint) -> bool --- // Verify framebuffer is complete - UnloadFramebuffer :: proc(id: c.uint) --- // Delete framebuffer from GPU + LoadFramebuffer :: proc() -> c.uint --- // Load an empty framebuffer + FramebufferAttach :: proc(fboId, texId: c.uint, attachType: c.int, texType: c.int, mipLevel: c.int) --- // Attach texture/renderbuffer to a framebuffer + FramebufferComplete :: proc(id: c.uint) -> bool --- // Verify framebuffer is complete + UnloadFramebuffer :: proc(id: c.uint) --- // Delete framebuffer from GPU // Shaders management - LoadShaderCode :: proc(vsCode, fsCode: cstring) -> c.uint --- // Load shader from code strings - CompileShader :: proc(shaderCode: cstring, type: c.int) -> c.uint --- // Compile custom shader and return shader id (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER) - LoadShaderProgram :: proc(vShaderId, fShaderId: c.uint) -> c.uint --- // Load custom shader program - UnloadShaderProgram :: proc(id: c.uint) --- // Unload shader program - GetLocationUniform :: proc(shaderId: c.uint, uniformName: cstring) -> c.int --- // Get shader location uniform - GetLocationAttrib :: proc(shaderId: c.uint, attribName: cstring) -> c.int --- // Get shader location attribute - SetUniform :: proc(locIndex: c.int, value: rawptr, uniformType: c.int, count: c.int) --- // Set shader value uniform - SetUniformMatrix :: proc(locIndex: c.int, mat: Matrix) --- // Set shader value matrix - SetUniformSampler :: proc(locIndex: c.int, textureId: c.uint) --- // Set shader value sampler - SetShader :: proc(id: c.uint, locs: [^]c.int) --- // Set shader currently active (id and locations) + LoadShaderCode :: proc(vsCode, fsCode: cstring) -> c.uint --- // Load shader from code strings + CompileShader :: proc(shaderCode: cstring, type: c.int) -> c.uint --- // Compile custom shader and return shader id (type: VERTEX_SHADER, FRAGMENT_SHADER, COMPUTE_SHADER) + LoadShaderProgram :: proc(vShaderId, fShaderId: c.uint) -> c.uint --- // Load custom shader program + UnloadShaderProgram :: proc(id: c.uint) --- // Unload shader program + GetLocationUniform :: proc(shaderId: c.uint, uniformName: cstring) -> c.int --- // Get shader location uniform + GetLocationAttrib :: proc(shaderId: c.uint, attribName: cstring) -> c.int --- // Get shader location attribute + SetUniform :: proc(locIndex: c.int, value: rawptr, uniformType: c.int, count: c.int) --- // Set shader value uniform + SetUniformMatrix :: proc(locIndex: c.int, mat: Matrix) --- // Set shader value matrix + SetUniformSampler :: proc(locIndex: c.int, textureId: c.uint) --- // Set shader value sampler + SetShader :: proc(id: c.uint, locs: [^]c.int) --- // Set shader currently active (id and locations) // Compute shader management - LoadComputeShaderProgram :: proc(shaderId: c.uint) -> c.uint --- // Load compute shader program - ComputeShaderDispatch :: proc(groupX, groupY, groupZ: c.uint) --- // Dispatch compute shader (equivalent to *draw* for graphics pipeline) + LoadComputeShaderProgram :: proc(shaderId: c.uint) -> c.uint --- // Load compute shader program + ComputeShaderDispatch :: proc(groupX, groupY, groupZ: c.uint) --- // Dispatch compute shader (equivalent to *draw* for graphics pipeline) // Shader buffer storage object management (ssbo) - LoadShaderBuffer :: proc(size: c.uint, data: rawptr, usageHint: c.int) -> c.uint --- // Load shader storage buffer object (SSBO) - UnloadShaderBuffer :: proc(ssboId: c.uint) --- // Unload shader storage buffer object (SSBO) - UpdateShaderBuffer :: proc(id: c.uint, data: rawptr, dataSize: c.uint, offset: c.uint) --- // Update SSBO buffer data - BindShaderBuffer :: proc(id: c.uint, index: c.uint) --- // Bind SSBO buffer - ReadShaderBuffer :: proc(id: c.uint, dest: rawptr, count: c.uint, offset: c.uint) --- // Read SSBO buffer data (GPU->CPU) - CopyShaderBuffer :: proc(destId, srcId: c.uint, destOffset, srcOffset: c.uint, count: c.uint) --- // Copy SSBO data between buffers - GetShaderBufferSize :: proc(id: c.uint) -> c.uint --- // Get SSBO buffer size + LoadShaderBuffer :: proc(size: c.uint, data: rawptr, usageHint: c.int) -> c.uint --- // Load shader storage buffer object (SSBO) + UnloadShaderBuffer :: proc(ssboId: c.uint) --- // Unload shader storage buffer object (SSBO) + UpdateShaderBuffer :: proc(id: c.uint, data: rawptr, dataSize: c.uint, offset: c.uint) --- // Update SSBO buffer data + BindShaderBuffer :: proc(id: c.uint, index: c.uint) --- // Bind SSBO buffer + ReadShaderBuffer :: proc(id: c.uint, dest: rawptr, count: c.uint, offset: c.uint) --- // Read SSBO buffer data (GPU->CPU) + CopyShaderBuffer :: proc(destId, srcId: c.uint, destOffset, srcOffset: c.uint, count: c.uint) --- // Copy SSBO data between buffers + GetShaderBufferSize :: proc(id: c.uint) -> c.uint --- // Get SSBO buffer size // Buffer management - BindImageTexture :: proc(id: c.uint, index: c.uint, format: c.int, readonly: bool) --- // Bind image texture + BindImageTexture :: proc(id: c.uint, index: c.uint, format: c.int, readonly: bool) --- // Bind image texture // Matrix state management - GetMatrixModelview :: proc() -> Matrix --- // Get internal modelview matrix - GetMatrixProjection :: proc() -> Matrix --- // Get internal projection matrix - GetMatrixTransform :: proc() -> Matrix --- // Get internal accumulated transform matrix + GetMatrixModelview :: proc() -> Matrix --- // Get internal modelview matrix + GetMatrixProjection :: proc() -> Matrix --- // Get internal projection matrix + GetMatrixTransform :: proc() -> Matrix --- // Get internal accumulated transform matrix GetMatrixProjectionStereo :: proc(eye: c.int) -> Matrix --- // Get internal projection matrix for stereo render (selected eye) GetMatrixViewOffsetStereo :: proc(eye: c.int) -> Matrix --- // Get internal view offset matrix for stereo render (selected eye) - SetMatrixProjection :: proc(proj: Matrix) --- // Set a custom projection matrix (replaces internal projection matrix) - SetMatrixModelview :: proc(view: Matrix) --- // Set a custom modelview matrix (replaces internal modelview matrix) - SetMatrixProjectionStereo :: proc(right, left: Matrix) --- // Set eyes projection matrices for stereo rendering - SetMatrixViewOffsetStereo :: proc(right, left: Matrix) --- // Set eyes view offsets matrices for stereo rendering + SetMatrixProjection :: proc(proj: Matrix) --- // Set a custom projection matrix (replaces internal projection matrix) + SetMatrixModelview :: proc(view: Matrix) --- // Set a custom modelview matrix (replaces internal modelview matrix) + SetMatrixProjectionStereo :: proc(right, left: Matrix) --- // Set eyes projection matrices for stereo rendering + SetMatrixViewOffsetStereo :: proc(right, left: Matrix) --- // Set eyes view offsets matrices for stereo rendering // Quick and dirty cube/quad buffers load->draw->unload LoadDrawCube :: proc() --- // Load and draw a cube diff --git a/src_assets/test_level.blend b/src_assets/test_level.blend index 898fef7..588a212 100644 --- a/src_assets/test_level.blend +++ b/src_assets/test_level.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5f5de4f5ba916f473b00f6f53a94af7d602ceaeede412b20aa50d1304e6fc07c -size 511651 +oid sha256:343a668334415b72f422920c2b3f543bdd50b6829f82bac3a3aaac8505db987d +size 1021009 diff --git a/src_assets/test_level.blend1 b/src_assets/test_level.blend1 index 1babbcd..24f9bae 100644 --- a/src_assets/test_level.blend1 +++ b/src_assets/test_level.blend1 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:533225496bc26bb37bc4a1d760b34beb5868bee3835923c2ab78e1f2de05672c -size 511650 +oid sha256:99b4a2e56bd48a2ab3d3a9704f10952a9c3eeabe501e134828306d9a4aa82efb +size 1010561