Merge branch 'main' into dds-textures

This commit is contained in:
Giuseppe Modarelli committed 2023-02-28 12:48:58 +01:00
commit ef8bb66eb1
35 files changed
+4739 -1722

No files matched your search

+1
View File
@@ -21,6 +21,7 @@
*.o filter=lfs diff=lfs merge=lfs -text
*.so filter=lfs diff=lfs merge=lfs -text
*.a filter=lfs diff=lfs merge=lfs -text
*.dds filter=lfs diff=lfs merge=lfs -text
libs/zwin32/bin/x64/dxc filter=lfs diff=lfs merge=lfs -text
libs/zwin32/bin/x64/libdxcompiler.so.3.7 filter=lfs diff=lfs merge=lfs -text
libs/zsdl/libs/macos/Frameworks/SDL2.framework/SDL2 filter=lfs diff=lfs merge=lfs -text
+1
View File
@@ -29,6 +29,7 @@
!*.flac
!*.blend
!*.hiplc
!*.dds
!.ignore
!.vimrc
+1 -1
View File
@@ -26,7 +26,7 @@ Library | Latest version | Description
**[zgui](libs/zgui)** | 0.9.5 | Easy to use [dear imgui](https://github.com/ocornut/imgui) bindings (includes [ImPlot](https://github.com/epezent/implot))
**[zaudio](libs/zaudio)** | 0.9.3 | Fully-featured audio library built on top of [miniaudio](https://github.com/mackron/miniaudio)
**[zmath](libs/zmath)** | 0.9.5 | SIMD math library for game developers
**[zstbi](libs/zstbi)** | 0.9.2 | Image reading, writing and resizing with [stb](https://github.com/nothings/stb) libraries
**[zstbi](libs/zstbi)** | 0.9.3 | Image reading, writing and resizing with [stb](https://github.com/nothings/stb) libraries
**[zmesh](libs/zmesh)** | 0.9.0 | Loading, generating, processing and optimizing triangle meshes
**[ztracy](libs/ztracy)** | 0.9.0 | Support for CPU profiling with [Tracy](https://github.com/wolfpld/tracy)
**[zpool](libs/zpool)** | 0.9.0 | Generic pool & handle implementation
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+60 -11
View File
@@ -31,18 +31,67 @@ test "zflecs.entities.basics" {
ecs.add(world, alice, Walking);
const str = ecs.type_str(world, ecs.get_type(world, alice));
defer ecs.os_free(str);
defer ecs.os.free(str);
std.debug.print("[{s}]\n", .{str});
ecs.remove(world, alice, Walking);
var it = ecs.term_iter(world, &.{ .id = ecs.id(Position) });
while (ecs.term_next(&it)) {
const positions = ecs.field(&it, Position, 1);
for (positions.?, 0..) |p, i| {
std.debug.print("{?s}: ({d}, {d})\n", .{ ecs.get_name(world, it.entities.?[i]), p.x, p.y });
{
var it = ecs.term_iter(world, &.{ .id = ecs.id(Position) });
while (ecs.term_next(&it)) {
if (ecs.field(&it, Position, 1)) |positions| {
for (positions, 0..) |p, i| {
std.debug.print(
"Term loop: {?s}: ({d}, {d})\n",
.{ ecs.get_name(world, it.entities.?[i]), p.x, p.y },
);
}
}
}
}
{
var desc = ecs.filter_desc_t{};
desc.terms[0].id = ecs.id(Position);
const filter = try ecs.filter_init(world, &desc);
defer ecs.filter_fini(filter);
}
{
const filter = try ecs.filter_init(world, &.{
.terms = [_]ecs.term_t{
.{ .id = ecs.id(Position) },
.{ .id = ecs.id(Walking) },
} ++ ecs.array(ecs.term_t, ecs.TERM_DESC_CACHE_SIZE - 2),
});
defer ecs.filter_fini(filter);
var it = ecs.filter_iter(world, filter);
while (ecs.filter_next(&it)) {
for (it.get_entities().?) |e| {
std.debug.print("Filter loop: {?s}\n", .{ecs.get_name(world, e)});
}
}
}
{
const query = _: {
var desc = ecs.query_desc_t{};
desc.filter.terms[0].id = ecs.id(Position);
break :_ try ecs.query_init(world, &desc);
};
defer ecs.query_fini(query);
}
{
const query = try ecs.query_init(world, &.{
.filter = .{
.terms = [_]ecs.term_t{.{ .id = ecs.id(Position) }} ++
ecs.array(ecs.term_t, ecs.TERM_DESC_CACHE_SIZE - 1),
},
});
defer ecs.query_fini(query);
}
}
fn registerComponents(world: *ecs.world_t) void {
@@ -129,13 +178,13 @@ test "zflecs.basic" {
}
const e0_type_str = ecs.type_str(world, ecs.get_type(world, e0));
defer ecs.os_free(e0_type_str);
defer ecs.os.free(e0_type_str);
const e0_table_str = ecs.table_str(world, ecs.get_table(world, e0));
defer ecs.os_free(e0_table_str);
defer ecs.os.free(e0_table_str);
const e0_str = ecs.entity_str(world, e0);
defer ecs.os_free(e0_str);
defer ecs.os.free(e0_str);
std.debug.print("type str: {s}\n", .{e0_type_str});
std.debug.print("table str: {?s}\n", .{e0_table_str});
@@ -143,12 +192,12 @@ test "zflecs.basic" {
{
const str = ecs.type_str(world, ecs.get_type(world, ecs.id(Position)));
defer ecs.os_free(str);
defer ecs.os.free(str);
std.debug.print("{s}\n", .{str});
}
{
const str = ecs.id_str(world, ecs.id(Position));
defer ecs.os_free(str);
defer ecs.os.free(str);
std.debug.print("{?s}\n", .{str});
}
}
+165 -103
View File
@@ -12,6 +12,11 @@ pub const vector_t = opaque {};
pub const mixins_t = opaque {};
const filter_t_magic = 0x65637366;
pub const error_t = error{FlecsError};
fn make_error() error{FlecsError} {
return error.FlecsError;
}
//--------------------------------------------------------------------------------------------------
//
// Types for core API objects.
@@ -42,9 +47,6 @@ pub const header_t = extern struct {
type: i32 = 0,
mixins: ?*mixins_t = null,
};
const ID_CACHE_SIZE = 32;
const TERM_DESC_CACHE_SIZE = 16;
//--------------------------------------------------------------------------------------------------
//
// Function types.
@@ -205,6 +207,10 @@ pub const term_t = extern struct {
move: bool = true,
};
pub fn array(comptime T: type, comptime len: comptime_int) [len]T {
return [_]T{.{}} ** len;
}
pub const filter_t = extern struct {
hdr: header_t = .{ .magic = filter_t_magic },
@@ -238,6 +244,7 @@ pub const observer_t = extern struct {
binding_ctx_free: ctx_free_t,
observable: [*c]observable_t,
last_event_id: [*c]i32,
last_event_id_storage: i32,
register_id: id_t,
term_index: i32,
is_monitor: bool,
@@ -466,6 +473,13 @@ pub const iter_t = extern struct {
callback: iter_action_t,
fini: iter_fini_action_t,
chain_it: ?*iter_t,
pub fn get_entities(iter: iter_t) ?[]entity_t {
if (iter.entities) |ptr| {
return ptr[0..@intCast(usize, iter.count)];
}
return null;
}
};
//--------------------------------------------------------------------------------------------------
//
@@ -553,17 +567,17 @@ pub const map_params_t = extern struct {
//--------------------------------------------------------------------------------------------------
pub const query_desc_t = extern struct {
_canary: i32 = 0,
filter: filter_desc_t,
order_by_component: entity_t,
order_by: ?order_by_action_t,
sort_table: ?sort_table_action_t,
group_by_id: id_t,
group_by: ?group_by_action_t,
on_group_create: ?group_create_action_t,
on_group_delete: ?group_delete_action_t,
group_by_ctx: ?*anyopaque,
group_by_ctx_free: ?ctx_free_t,
parent: ?*query_t,
filter: filter_desc_t = .{},
order_by_component: entity_t = 0,
order_by: ?order_by_action_t = null,
sort_table: ?sort_table_action_t = null,
group_by_id: id_t = 0,
group_by: ?group_by_action_t = null,
on_group_create: ?group_create_action_t = null,
on_group_delete: ?group_delete_action_t = null,
group_by_ctx: ?*anyopaque = null,
group_by_ctx_free: ?ctx_free_t = null,
parent: ?*query_t = null,
};
pub const component_desc_t = extern struct {
@@ -572,6 +586,8 @@ pub const component_desc_t = extern struct {
type: type_info_t,
};
pub const ID_CACHE_SIZE = 32;
pub const entity_desc_t = extern struct {
_canary: i32 = 0,
id: entity_t = 0,
@@ -584,6 +600,8 @@ pub const entity_desc_t = extern struct {
add_expr: ?[*:0]const u8 = null,
};
pub const TERM_DESC_CACHE_SIZE = 16;
pub const filter_desc_t = extern struct {
_canary: i32 = 0,
terms: [TERM_DESC_CACHE_SIZE]term_t = [_]term_t{.{}} ** TERM_DESC_CACHE_SIZE,
@@ -596,6 +614,25 @@ pub const filter_desc_t = extern struct {
entity: entity_t = 0,
};
pub const OBSERVER_DESC_EVENT_COUNT_MAX = 8;
pub const observer_desc_t = extern struct {
_canary: i32 = 0,
entity: entity_t = 0,
filter: filter_desc_t = .{},
events: [OBSERVER_DESC_EVENT_COUNT_MAX]entity_t = [_]entity_t{0} ** OBSERVER_DESC_EVENT_COUNT_MAX,
yield_existing: bool = false,
callback: iter_action_t,
run: ?run_action_t = null,
ctx: ?*anyopaque = null,
binding_ctx: ?*anyopaque = null,
ctx_free: ?ctx_free_t = null,
binding_ctx_free: ?ctx_free_t = null,
observable: ?*poly_t = null,
last_event_id: ?*i32 = null,
term_index: i32 = 0,
};
pub const world_info_t = extern struct {
last_component_id: entity_t,
last_id: entity_t,
@@ -864,6 +901,10 @@ extern fn ecs_new_low_id(world: *world_t) entity_t;
pub const new_w_id = ecs_new_w_id;
extern fn ecs_new_w_id(world: *world_t, id: id_t) entity_t;
/// `pub fn new_w_table(world: *world_t, table: *table_t) entity_t`
pub const new_w_table = ecs_new_w_table;
extern fn ecs_new_w_table(world: *world_t, table: *table_t) entity_t;
/// `pub fn entity_init(world: *world_t, desc: *const entity_desc_t) entity_t`
pub const entity_init = ecs_entity_init;
extern fn ecs_entity_init(world: *world_t, desc: *const entity_desc_t) entity_t;
@@ -1222,9 +1263,12 @@ extern fn ecs_get_hooks_id(world: *const world_t, id: entity_t) *const type_hook
/// `pub fn id_is_tag(world: *const world_t, id: id_t) bool;
pub const id_is_tag = ecs_id_is_tag;
// TODO: flecs upstream: missing const
extern fn ecs_id_is_tag(world: *const world_t, id: id_t) bool;
/// `pub fn id_is_union(world: *const world_t, id: id_t) bool;
pub const id_is_union = ecs_id_is_union;
extern fn ecs_id_is_union(world: *const world_t, id: id_t) bool;
/// `pub fn id_in_use(world: *const world_t, id: id_t) bool`
pub const id_in_use = ecs_id_in_use;
// TODO: flecs upstream: missing const
@@ -1322,8 +1366,9 @@ extern fn ecs_term_move(src: *term_t) term_t;
pub const term_fini = ecs_term_fini;
extern fn ecs_term_fini(term: *term_t) void;
/// `pub fn filter_init(world: *world_t, desc: *const filter_desc_t) ?*filter_t;`
pub const filter_init = filter_init;
pub fn filter_init(world: *world_t, desc: *const filter_desc_t) error_t!*filter_t {
return ecs_filter_init(world, desc) orelse return make_error();
}
extern fn ecs_filter_init(world: *world_t, desc: *const filter_desc_t) ?*filter_t;
/// `pub fn filter_fini(filter: *filter_t) void`
@@ -1378,7 +1423,14 @@ extern fn ecs_filter_copy(dst: *filter_t, src: *const filter_t) void;
// Functions for working with `query_t`.
//
//--------------------------------------------------------------------------------------------------
// TODO:
pub fn query_init(world: *world_t, desc: *const query_desc_t) error_t!*query_t {
return ecs_query_init(world, desc) orelse return make_error();
}
extern fn ecs_query_init(world: *world_t, desc: *const query_desc_t) ?*query_t;
/// `pub fn query_fini(query: *query_t) void`
pub const query_fini = ecs_query_fini;
extern fn ecs_query_fini(query: *query_t) void;
//--------------------------------------------------------------------------------------------------
//
// Functions for working with events and observers.
@@ -1491,11 +1543,18 @@ pub const iter_str = ecs_iter_str;
extern fn ecs_iter_str(it: *const iter_t) ?[*:0]u8;
//--------------------------------------------------------------------------------------------------
//
// Functions for working with `table_t`.
//
//--------------------------------------------------------------------------------------------------
// TODO:
//--------------------------------------------------------------------------------------------------
//
// Declarative functions (ECS_* macros in flecs)
//
//--------------------------------------------------------------------------------------------------
// TODO: We support only one `world_t` at the time because type ids are stored in a global static memory.
// We need to reset those ids to zero when the world is destroyed.
// We need to reset those ids to zero when the world is destroyed
// (we do this in `pub fn fini(world: *world_t) i32`).
var num_worlds: u32 = 0;
var component_ids_hm = std.AutoHashMap(*id_t, u0).init(std.heap.page_allocator);
@@ -1612,92 +1671,95 @@ pub const time_t = extern struct {
sec: u32,
nanosec: u32,
};
pub const os_thread_t = usize;
pub const os_cond_t = usize;
pub const os_mutex_t = usize;
pub const os_dl_t = usize;
pub const os_sock_t = usize;
pub const os_thread_id_t = u64;
pub const os_proc_t = *const fn () callconv(.C) void;
pub const os_api_init_t = *const fn () callconv(.C) void;
pub const os_api_fini_t = *const fn () callconv(.C) void;
pub const os_api_malloc_t = *const fn (size_t) callconv(.C) ?*anyopaque;
pub const os_api_free_t = *const fn (?*anyopaque) callconv(.C) void;
pub const os_api_realloc_t = *const fn (?*anyopaque, size_t) callconv(.C) ?*anyopaque;
pub const os_api_calloc_t = *const fn (size_t) callconv(.C) ?*anyopaque;
pub const os_api_strdup_t = *const fn ([*:0]const u8) callconv(.C) [*c]u8;
pub const os_thread_callback_t = *const fn (?*anyopaque) callconv(.C) ?*anyopaque;
pub const os_api_thread_new_t = *const fn (os_thread_callback_t, ?*anyopaque) callconv(.C) os_thread_t;
pub const os_api_thread_join_t = *const fn (os_thread_t) callconv(.C) ?*anyopaque;
pub const os_api_thread_self_t = *const fn () callconv(.C) os_thread_id_t;
pub const os_api_ainc_t = *const fn (*i32) callconv(.C) i32;
pub const os_api_lainc_t = *const fn (*i64) callconv(.C) i64;
pub const os_api_mutex_new_t = *const fn () callconv(.C) os_mutex_t;
pub const os_api_mutex_lock_t = *const fn (os_mutex_t) callconv(.C) void;
pub const os_api_mutex_unlock_t = *const fn (os_mutex_t) callconv(.C) void;
pub const os_api_mutex_free_t = *const fn (os_mutex_t) callconv(.C) void;
pub const os_api_cond_new_t = *const fn () callconv(.C) os_cond_t;
pub const os_api_cond_free_t = *const fn (os_cond_t) callconv(.C) void;
pub const os_api_cond_signal_t = *const fn (os_cond_t) callconv(.C) void;
pub const os_api_cond_broadcast_t = *const fn (os_cond_t) callconv(.C) void;
pub const os_api_cond_wait_t = *const fn (os_cond_t, os_mutex_t) callconv(.C) void;
pub const os_api_sleep_t = *const fn (i32, i32) callconv(.C) void;
pub const os_api_enable_high_timer_resolution_t = *const fn (bool) callconv(.C) void;
pub const os_api_get_time_t = *const fn (*time_t) callconv(.C) void;
pub const os_api_now_t = *const fn () callconv(.C) u64;
pub const os_api_log_t = *const fn (i32, [*c]const u8, i32, [*:0]const u8) callconv(.C) void;
pub const os_api_abort_t = *const fn () callconv(.C) void;
pub const os_api_dlopen_t = *const fn ([*:0]const u8) callconv(.C) os_dl_t;
pub const os_api_dlproc_t = *const fn (os_dl_t, [*:0]const u8) callconv(.C) os_proc_t;
pub const os_api_dlclose_t = *const fn (os_dl_t) callconv(.C) void;
pub const os_api_module_to_path_t = *const fn ([*:0]const u8) callconv(.C) [*:0]u8;
const os_api_t = extern struct {
init_: os_api_init_t,
fini_: os_api_fini_t,
malloc_: os_api_malloc_t,
realloc_: os_api_realloc_t,
calloc_: os_api_calloc_t,
free_: os_api_free_t,
strdup_: os_api_strdup_t,
thread_new_: os_api_thread_new_t,
thread_join_: os_api_thread_join_t,
thread_self_: os_api_thread_self_t,
ainc_: os_api_ainc_t,
adec_: os_api_ainc_t,
lainc_: os_api_lainc_t,
ladec_: os_api_lainc_t,
mutex_new_: os_api_mutex_new_t,
mutex_free_: os_api_mutex_free_t,
mutex_lock_: os_api_mutex_lock_t,
mutex_unlock_: os_api_mutex_lock_t,
cond_new_: os_api_cond_new_t,
cond_free_: os_api_cond_free_t,
cond_signal_: os_api_cond_signal_t,
cond_broadcast_: os_api_cond_broadcast_t,
cond_wait_: os_api_cond_wait_t,
sleep_: os_api_sleep_t,
now_: os_api_now_t,
get_time_: os_api_get_time_t,
log_: os_api_log_t,
abort_: os_api_abort_t,
dlopen_: os_api_dlopen_t,
dlproc_: os_api_dlproc_t,
dlclose_: os_api_dlclose_t,
module_to_dl_: os_api_module_to_path_t,
module_to_etc_: os_api_module_to_path_t,
log_level_: i32,
log_indent_: i32,
log_last_error_: i32,
log_last_timestamp_: i64,
flags_: flags32_t,
pub const os = struct {
pub const thread_t = usize;
pub const cond_t = usize;
pub const mutex_t = usize;
pub const dl_t = usize;
pub const sock_t = usize;
pub const thread_id_t = u64;
pub const proc_t = *const fn () callconv(.C) void;
pub const api_init_t = *const fn () callconv(.C) void;
pub const api_fini_t = *const fn () callconv(.C) void;
pub const api_malloc_t = *const fn (size_t) callconv(.C) ?*anyopaque;
pub const api_free_t = *const fn (?*anyopaque) callconv(.C) void;
pub const api_realloc_t = *const fn (?*anyopaque, size_t) callconv(.C) ?*anyopaque;
pub const api_calloc_t = *const fn (size_t) callconv(.C) ?*anyopaque;
pub const api_strdup_t = *const fn ([*:0]const u8) callconv(.C) [*c]u8;
pub const thread_callback_t = *const fn (?*anyopaque) callconv(.C) ?*anyopaque;
pub const api_thread_new_t = *const fn (thread_callback_t, ?*anyopaque) callconv(.C) thread_t;
pub const api_thread_join_t = *const fn (thread_t) callconv(.C) ?*anyopaque;
pub const api_thread_self_t = *const fn () callconv(.C) thread_id_t;
pub const api_ainc_t = *const fn (*i32) callconv(.C) i32;
pub const api_lainc_t = *const fn (*i64) callconv(.C) i64;
pub const api_mutex_new_t = *const fn () callconv(.C) mutex_t;
pub const api_mutex_lock_t = *const fn (mutex_t) callconv(.C) void;
pub const api_mutex_unlock_t = *const fn (mutex_t) callconv(.C) void;
pub const api_mutex_free_t = *const fn (mutex_t) callconv(.C) void;
pub const api_cond_new_t = *const fn () callconv(.C) cond_t;
pub const api_cond_free_t = *const fn (cond_t) callconv(.C) void;
pub const api_cond_signal_t = *const fn (cond_t) callconv(.C) void;
pub const api_cond_broadcast_t = *const fn (cond_t) callconv(.C) void;
pub const api_cond_wait_t = *const fn (cond_t, mutex_t) callconv(.C) void;
pub const api_sleep_t = *const fn (i32, i32) callconv(.C) void;
pub const api_enable_high_timer_resolution_t = *const fn (bool) callconv(.C) void;
pub const api_get_time_t = *const fn (*time_t) callconv(.C) void;
pub const api_now_t = *const fn () callconv(.C) u64;
pub const api_log_t = *const fn (i32, [*:0]const u8, i32, [*:0]const u8) callconv(.C) void;
pub const api_abort_t = *const fn () callconv(.C) void;
pub const api_dlopen_t = *const fn ([*:0]const u8) callconv(.C) dl_t;
pub const api_dlproc_t = *const fn (dl_t, [*:0]const u8) callconv(.C) proc_t;
pub const api_dlclose_t = *const fn (dl_t) callconv(.C) void;
pub const api_module_to_path_t = *const fn ([*:0]const u8) callconv(.C) [*:0]u8;
const api_t = extern struct {
init_: api_init_t,
fini_: api_fini_t,
malloc_: api_malloc_t,
realloc_: api_realloc_t,
calloc_: api_calloc_t,
free_: api_free_t,
strdup_: api_strdup_t,
thread_new_: api_thread_new_t,
thread_join_: api_thread_join_t,
thread_self_: api_thread_self_t,
ainc_: api_ainc_t,
adec_: api_ainc_t,
lainc_: api_lainc_t,
ladec_: api_lainc_t,
mutex_new_: api_mutex_new_t,
mutex_free_: api_mutex_free_t,
mutex_lock_: api_mutex_lock_t,
mutex_unlock_: api_mutex_lock_t,
cond_new_: api_cond_new_t,
cond_free_: api_cond_free_t,
cond_signal_: api_cond_signal_t,
cond_broadcast_: api_cond_broadcast_t,
cond_wait_: api_cond_wait_t,
sleep_: api_sleep_t,
now_: api_now_t,
get_time_: api_get_time_t,
log_: api_log_t,
abort_: api_abort_t,
dlopen_: api_dlopen_t,
dlproc_: api_dlproc_t,
dlclose_: api_dlclose_t,
module_to_dl_: api_module_to_path_t,
module_to_etc_: api_module_to_path_t,
log_level_: i32,
log_indent_: i32,
log_last_error_: i32,
log_last_timestamp_: i64,
flags_: flags32_t,
};
extern var ecs_os_api: api_t;
pub fn free(ptr: ?*anyopaque) void {
ecs_os_api.free_(ptr);
}
};
extern var ecs_os_api: os_api_t;
pub fn os_free(ptr: ?*anyopaque) void {
ecs_os_api.free_(ptr);
}
//--------------------------------------------------------------------------------------------------
comptime {
_ = @import("tests.zig");
+20
View File
@@ -93,6 +93,26 @@ while (...) {
}
```
### Building a shared library
If your project spans multiple zig modules that both use ImGui, such as an exe paired with a dll, you may want to build the `zgui` dependencies (`zgui_pkg.zgui_c_cpp`) as a shared library. This can be enabled with the `shared` build option. Then, in `build.zig`, use `zgui_pkg.link` to link `zgui` to all the modules that use ImGui.
When built this way, the ImGui context will be located in the shared library. However, the `zgui` zig code (which is compiled separately into each module) requires its own memory buffer which has to be initialized separately with `initNoContext`.
In your executable:
```zig
const zgui = @import("zgui");
zgui.init(allocator);
defer zgui.deinit();
```
In your shared library:
```zig
const zgui = @import("zgui");
zgui.initNoContext(allocator);
defer zgui.deinitNoContxt();
```
### DrawList API
```zig
+18 -1
View File
@@ -8,6 +8,7 @@ pub const Package = struct {
};
pub const Options = struct {
backend: Backend,
shared: bool = false,
};
options: Options,
@@ -25,6 +26,7 @@ pub const Package = struct {
) Package {
const step = b.addOptions();
step.addOption(Backend, "backend", args.options.backend);
step.addOption(bool, "shared", args.options.shared);
const zgui_options = step.createModule();
@@ -35,7 +37,22 @@ pub const Package = struct {
},
});
const zgui_c_cpp = b.addStaticLibrary(.{
const zgui_c_cpp = if (args.options.shared) blk: {
const lib = b.addSharedLibrary(.{
.name = "zgui",
.target = target,
.optimize = optimize,
});
lib.install();
if (target.isWindows()) {
lib.defineCMacro("IMGUI_API", "__declspec(dllexport)");
lib.defineCMacro("IMPLOT_API", "__declspec(dllexport)");
lib.defineCMacro("ZGUI_API", "__declspec(dllexport)");
}
break :blk lib;
} else b.addStaticLibrary(.{
.name = "zgui",
.target = target,
.optimize = optimize,
+32 -10
View File
@@ -50,6 +50,17 @@ pub fn deinit() void {
mem_allocator = null;
}
}
pub fn initNoContext(allocator: std.mem.Allocator) void {
if (temp_buffer == null) {
temp_buffer = std.ArrayList(u8).init(allocator);
temp_buffer.?.resize(3 * 1024 + 1) catch unreachable;
}
}
pub fn deinitNoContext() void {
if (temp_buffer) |buf| {
buf.deinit();
}
}
extern fn zguiCreateContext(shared_font_atlas: ?*const anyopaque) Context;
extern fn zguiDestroyContext(ctx: ?Context) void;
extern fn zguiGetCurrentContext() ?Context;
@@ -92,16 +103,17 @@ extern fn zguiSetAllocatorFunctions(
free_func: ?*const fn (?*anyopaque, ?*anyopaque) callconv(.C) void,
) void;
//--------------------------------------------------------------------------------------------------
pub const ConfigFlags = enum(u32) {
none = 0,
nav_enable_keyboard = 1 << 0,
nav_enable_gamepad = 1 << 1,
nav_enable_set_mouse_pos = 1 << 2,
nav_no_capture_keyboard = 1 << 3,
no_mouse = 1 << 4,
no_mouse_cursor_change = 1 << 5,
is_srgb = 1 << 20,
is_touch_screen = 1 << 21,
pub const ConfigFlags = packed struct(u32) {
nav_enable_keyboard: bool = false,
nav_enable_gamepad: bool = false,
nav_enable_set_mouse_pos: bool = false,
nav_no_capture_keyboard: bool = false,
no_mouse: bool = false,
no_mouse_cursor_change: bool = false,
user_storage: u14 = 0,
is_srgb: bool = false,
is_touch_screen: bool = false,
_padding: u10 = 0,
};
pub const FontConfig = extern struct {
@@ -3061,6 +3073,15 @@ pub fn menuItem(label: [:0]const u8, args: MenuItem) bool {
return zguiMenuItem(label, if (args.shortcut) |s| s.ptr else null, args.selected, args.enabled);
}
const MenuItemPtr = struct {
shortcut: ?[:0]const u8 = null,
selected: *bool,
enabled: bool = true,
};
pub fn menuItemPtr(label: [:0]const u8, args: MenuItemPtr) bool {
return zguiMenuItemPtr(label, if (args.shortcut) |s| s.ptr else null, args.selected, args.enabled);
}
extern fn zguiBeginMenuBar() bool;
extern fn zguiEndMenuBar() void;
extern fn zguiBeginMainMenuBar() bool;
@@ -3068,6 +3089,7 @@ extern fn zguiEndMainMenuBar() void;
extern fn zguiBeginMenu(label: [*:0]const u8, enabled: bool) bool;
extern fn zguiEndMenu() void;
extern fn zguiMenuItem(label: [*:0]const u8, shortcut: ?[*:0]const u8, selected: bool, enabled: bool) bool;
extern fn zguiMenuItemPtr(label: [*:0]const u8, shortcut: ?[*:0]const u8, selected: *bool, enabled: bool) bool;
//--------------------------------------------------------------------------------------------------
//
// Popups
+10 -1
View File
@@ -1,7 +1,11 @@
#include "./imgui/imgui.h"
#include "./imgui/implot.h"
#define ZGUI_API extern "C"
#ifndef ZGUI_API
#define ZGUI_API
#endif
extern "C" {
/*
#include <stdio.h>
@@ -1427,6 +1431,10 @@ ZGUI_API bool zguiMenuItem(const char* label, const char* shortcut, bool selecte
return ImGui::MenuItem(label, shortcut, selected, enabled);
}
ZGUI_API bool zguiMenuItemPtr(const char* label, const char* shortcut, bool* selected, bool enabled) {
return ImGui::MenuItem(label, shortcut, selected, enabled);
}
ZGUI_API void zguiBeginTooltip(void) {
ImGui::BeginTooltip();
}
@@ -2300,3 +2308,4 @@ ZGUI_API void zguiPlot_EndPlot(void) {
ImPlot::EndPlot();
}
//--------------------------------------------------------------------------------------------------
} /* extern "C" */
+1 -1
View File
@@ -2544,7 +2544,7 @@ pub fn inverseDet(m: Mat, out_det: ?*F32x4) Mat {
out_det.?.* = det;
}
if (math.approxEqAbs(f32, det[0], 0.0, 0.0001)) {
if (math.approxEqAbs(f32, det[0], 0.0, math.f32_epsilon)) {
return .{
f32x4(0.0, 0.0, 0.0, 0.0),
f32x4(0.0, 0.0, 0.0, 0.0),
+1
View File
@@ -58,6 +58,7 @@ pub const Package = struct {
zmesh_c_cpp.addCSourceFile(thisDir() ++ "/libs/meshoptimizer/vfetchanalyzer.cpp", &.{""});
zmesh_c_cpp.addCSourceFile(thisDir() ++ "/libs/meshoptimizer/overdrawoptimizer.cpp", &.{""});
zmesh_c_cpp.addCSourceFile(thisDir() ++ "/libs/meshoptimizer/overdrawanalyzer.cpp", &.{""});
zmesh_c_cpp.addCSourceFile(thisDir() ++ "/libs/meshoptimizer/simplifier.cpp", &.{""});
zmesh_c_cpp.addCSourceFile(thisDir() ++ "/libs/meshoptimizer/allocator.cpp", &.{""});
zmesh_c_cpp.addIncludePath(thisDir() ++ "/libs/cgltf");
@@ -187,7 +187,7 @@ size_t meshopt_generateVertexRemap(unsigned int* destination, const unsigned int
using namespace meshopt;
assert(indices || index_count == vertex_count);
assert(index_count % 3 == 0);
assert(!indices || index_count % 3 == 0);
assert(vertex_size > 0 && vertex_size <= 256);
meshopt_Allocator allocator;
+21 -11
View File
@@ -1,7 +1,7 @@
/**
* meshoptimizer - version 0.17
* meshoptimizer - version 0.18
*
* Copyright (C) 2016-2021, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Copyright (C) 2016-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
*
* This library is distributed under the MIT License. See notice at the end of this file.
@@ -12,7 +12,7 @@
#include <stddef.h>
/* Version macro; major * 1000 + minor * 10 + patch */
#define MESHOPTIMIZER_VERSION 170 /* 0.17 */
#define MESHOPTIMIZER_VERSION 180 /* 0.18 */
/* If no API is defined, assume default */
#ifndef MESHOPTIMIZER_API
@@ -313,7 +313,16 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterQuat(void* destination, size
MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data);
/**
* Experimental: Mesh simplifier
* Simplification options
*/
enum
{
/* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */
meshopt_SimplifyLockBorder = 1 << 0,
};
/**
* Mesh simplifier
* Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
* The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error.
* If not all attributes from the input mesh are required, it's recommended to reindex the mesh using meshopt_generateShadowIndexBuffer prior to simplification.
@@ -324,9 +333,10 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_
* destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
* vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
* target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
* options must be a bitmask composed of meshopt_SimplifyX options; 0 is a safe default
* result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
*/
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error);
MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error);
/**
* Experimental: Mesh simplifier (sloppy)
@@ -356,12 +366,12 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count);
/**
* Experimental: Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
* Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
*
* Absolute error must be *divided* by the scaling factor before passing it to meshopt_simplify as target_error
* Relative error returned by meshopt_simplify via result_error must be *multiplied* by the scaling factor to get absolute error.
*/
MESHOPTIMIZER_EXPERIMENTAL float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
MESHOPTIMIZER_API float meshopt_simplifyScale(const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
/**
* Mesh stripifier
@@ -605,7 +615,7 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s
template <typename T>
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
template <typename T>
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = 0);
template <typename T>
inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = 0);
template <typename T>
@@ -940,12 +950,12 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const
}
template <typename T>
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error)
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* result_error)
{
meshopt_IndexAdapter<T> in(0, indices, index_count);
meshopt_IndexAdapter<T> out(destination, 0, index_count);
return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options, result_error);
}
template <typename T>
@@ -1034,7 +1044,7 @@ inline void meshopt_spatialSortTriangles(T* destination, const T* indices, size_
#endif
/**
* Copyright (c) 2016-2021 Arseny Kapoulkine
* Copyright (c) 2016-2022 Arseny Kapoulkine
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
+18 -4
View File
@@ -252,7 +252,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int
return false;
}
static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge)
static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options)
{
memset(loop, -1, vertex_count * sizeof(unsigned int));
memset(loopback, -1, vertex_count * sizeof(unsigned int));
@@ -274,7 +274,15 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
{
unsigned int target = edges[j].next;
if (!hasEdge(adjacency, target, vertex))
if (target == vertex)
{
// degenerate triangles have two distinct edges instead of three, and the self edge
// is bi-directional by definition; this can break border/seam classification by "closing"
// the open edge from another triangle and falsely marking the vertex as manifold
// instead we mark the vertex as having >1 open edges which turns it into locked/complex
openinc[vertex] = openout[vertex] = vertex;
}
else if (!hasEdge(adjacency, target, vertex))
{
openinc[target] = (openinc[target] == ~0u) ? vertex : target;
openout[vertex] = (openout[vertex] == ~0u) ? target : vertex;
@@ -354,6 +362,11 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
}
}
if (options & meshopt_SimplifyLockBorder)
for (size_t i = 0; i < vertex_count; ++i)
if (result[i] == Kind_Border)
result[i] = Kind_Locked;
#if TRACE
printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n",
int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3]));
@@ -1264,7 +1277,7 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0;
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
#endif
size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* out_result_error)
size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
{
using namespace meshopt;
@@ -1272,6 +1285,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
assert(vertex_positions_stride % sizeof(float) == 0);
assert(target_index_count <= index_count);
assert((options & ~(meshopt_SimplifyLockBorder)) == 0);
meshopt_Allocator allocator;
@@ -1291,7 +1305,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count);
unsigned int* loop = allocator.allocate<unsigned int>(vertex_count);
unsigned int* loopback = allocator.allocate<unsigned int>(vertex_count);
classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge);
classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options);
#if TRACE
size_t unique_positions = 0;
+74
View File
@@ -152,6 +152,57 @@ pub inline fn analyzeVertexFetch(
return meshopt_analyzeVertexFetch(indices.ptr, indices.len, vertex_count, vertex_size);
}
// Simplifier
pub inline fn simplify(
comptime T: type,
destination: []u32,
indices: []const u32,
index_count: usize,
vertices: []const T,
vertex_count: usize,
target_index_count: usize,
target_error: f32,
options: u32,
out_result_error: *f32,
) usize {
return meshopt_simplify(
destination.ptr,
indices.ptr,
index_count,
vertices.ptr,
vertex_count,
@sizeOf(T),
target_index_count,
target_error,
options,
out_result_error,
);
}
pub inline fn simplifySloppy(
comptime T: type,
destination: []u32,
indices: []const u32,
index_count: usize,
vertices: []const T,
vertex_count: usize,
target_index_count: usize,
target_error: f32,
out_result_error: *f32,
) usize {
return meshopt_simplifySloppy(
destination.ptr,
indices.ptr,
index_count,
vertices.ptr,
vertex_count,
@sizeOf(T),
target_index_count,
target_error,
out_result_error,
);
}
// Mesh shading
pub inline fn buildMeshletsBound(index_count: usize, max_vertices: usize, max_triangles: usize) usize {
return meshopt_buildMeshletsBound(index_count, max_vertices, max_triangles);
@@ -255,6 +306,29 @@ extern fn meshopt_analyzeVertexFetch(
vertex_count: usize,
vertex_size: usize,
) VertexFetchStatistics;
extern fn meshopt_simplify(
destination: [*]u32,
indices: [*]const u32,
index_count: usize,
vertices: *const anyopaque,
vertex_count: usize,
vertex_stride: usize,
target_index_count: usize,
target_error: f32,
options: u32,
out_result_error: *f32,
) usize;
extern fn meshopt_simplifySloppy(
destination: [*]u32,
indices: [*]const u32,
index_count: usize,
vertices: *const anyopaque,
vertex_count: usize,
vertex_stride: usize,
target_index_count: usize,
target_error: f32,
out_result_error: *f32,
) usize;
extern fn meshopt_buildMeshletsBound(
index_count: usize,
max_vertices: usize,
+5
View File
@@ -30,4 +30,9 @@ pub fn main() !void {
gl.clearBufferfv(gl.COLOR, 0, &[_]f32{ 0.2, 0.4, 0.8, 1.0 });
}
fn getProcAddress(name: [:0]const u8) ?*anyopaque {
// Load GL function pointer here
// You could use `zsdl.gl.getProcAddress() or `zglfw.getProcAddress()`
}
```
+1 -1
View File
@@ -2414,7 +2414,7 @@ var loaderFunc: *const fn ([:0]const u8) ?*anyopaque = undefined;
fn getProcAddress(comptime T: type, name: [:0]const u8) !T {
if (loaderFunc(name)) |addr| {
return @ptrCast(T, @alignCast(@sizeOf(usize), addr));
return @intToPtr(T, @ptrToInt(addr));
}
std.log.debug("zopengl: {s} not found", .{name});
return error.OpenGL_FunctionNotFound;
+1 -1
View File
@@ -67,7 +67,7 @@ pub fn Handle(
const UInt = utils.UInt;
const AddressableUInt = utils.AddressableUInt;
return struct {
return extern struct {
const Self = @This();
const HandleType = Self;
+500
View File
@@ -0,0 +1,500 @@
pub const Scancode = enum(u32) {
unknown = 0,
a = 4,
b = 5,
c = 6,
d = 7,
e = 8,
f = 9,
g = 10,
h = 11,
i = 12,
j = 13,
k = 14,
l = 15,
m = 16,
n = 17,
o = 18,
p = 19,
q = 20,
r = 21,
s = 22,
t = 23,
u = 24,
v = 25,
w = 26,
x = 27,
y = 28,
z = 29,
@"1" = 30,
@"2" = 31,
@"3" = 32,
@"4" = 33,
@"5" = 34,
@"6" = 35,
@"7" = 36,
@"8" = 37,
@"9" = 38,
@"0" = 39,
@"return" = 40,
escape = 41,
backspace = 42,
tab = 43,
space = 44,
minus = 45,
equals = 46,
leftbracket = 47,
rightbracket = 48,
backslash = 49,
nonushash = 50,
semicolon = 51,
apostrophe = 52,
grave = 53,
comma = 54,
period = 55,
slash = 56,
capslock = 57,
f1 = 58,
f2 = 59,
f3 = 60,
f4 = 61,
f5 = 62,
f6 = 63,
f7 = 64,
f8 = 65,
f9 = 66,
f10 = 67,
f11 = 68,
f12 = 69,
printscreen = 70,
scrolllock = 71,
pause = 72,
insert = 73,
home = 74,
pageup = 75,
delete = 76,
end = 77,
pagedown = 78,
right = 79,
left = 80,
down = 81,
up = 82,
numlockclear = 83,
kp_divide = 84,
kp_multiply = 85,
kp_minus = 86,
kp_plus = 87,
kp_enter = 88,
kp_1 = 89,
kp_2 = 90,
kp_3 = 91,
kp_4 = 92,
kp_5 = 93,
kp_6 = 94,
kp_7 = 95,
kp_8 = 96,
kp_9 = 97,
kp_0 = 98,
kp_period = 99,
nonusbackslash = 100,
application = 101,
power = 102,
kp_equals = 103,
f13 = 104,
f14 = 105,
f15 = 106,
f16 = 107,
f17 = 108,
f18 = 109,
f19 = 110,
f20 = 111,
f21 = 112,
f22 = 113,
f23 = 114,
f24 = 115,
execute = 116,
help = 117,
menu = 118,
select = 119,
stop = 120,
again = 121,
undo = 122,
cut = 123,
copy = 124,
paste = 125,
find = 126,
mute = 127,
volumeup = 128,
volumedown = 129,
kp_comma = 133,
kp_equalsas400 = 134,
international1 = 135,
international2 = 136,
international3 = 137,
international4 = 138,
international5 = 139,
international6 = 140,
international7 = 141,
international8 = 142,
international9 = 143,
lang1 = 144,
lang2 = 145,
lang3 = 146,
lang4 = 147,
lang5 = 148,
lang6 = 149,
lang7 = 150,
lang8 = 151,
lang9 = 152,
alterase = 153,
sysreq = 154,
cancel = 155,
clear = 156,
prior = 157,
return2 = 158,
separator = 159,
out = 160,
oper = 161,
clearagain = 162,
crsel = 163,
exsel = 164,
kp_00 = 176,
kp_000 = 177,
thousandsseparator = 178,
decimalseparator = 179,
currencyunit = 180,
currencysubunit = 181,
kp_leftparen = 182,
kp_rightparen = 183,
kp_leftbrace = 184,
kp_rightbrace = 185,
kp_tab = 186,
kp_backspace = 187,
kp_a = 188,
kp_b = 189,
kp_c = 190,
kp_d = 191,
kp_e = 192,
kp_f = 193,
kp_xor = 194,
kp_power = 195,
kp_percent = 196,
kp_less = 197,
kp_greater = 198,
kp_ampersand = 199,
kp_dblampersand = 200,
kp_verticalbar = 201,
kp_dblverticalbar = 202,
kp_colon = 203,
kp_hash = 204,
kp_space = 205,
kp_at = 206,
kp_exclam = 207,
kp_memstore = 208,
kp_memrecall = 209,
kp_memclear = 210,
kp_memadd = 211,
kp_memsubtract = 212,
kp_memmultiply = 213,
kp_memdivide = 214,
kp_plusminus = 215,
kp_clear = 216,
kp_clearentry = 217,
kp_binary = 218,
kp_octal = 219,
kp_decimal = 220,
kp_hexadecimal = 221,
lctrl = 224,
lshift = 225,
lalt = 226,
lgui = 227,
rctrl = 228,
rshift = 229,
ralt = 230,
rgui = 231,
mode = 257,
audionext = 258,
audioprev = 259,
audiostop = 260,
audioplay = 261,
audiomute = 262,
mediaselect = 263,
www = 264,
mail = 265,
calculator = 266,
computer = 267,
ac_search = 268,
ac_home = 269,
ac_back = 270,
ac_forward = 271,
ac_stop = 272,
ac_refresh = 273,
ac_bookmarks = 274,
brightnessdown = 275,
brightnessup = 276,
displayswitch = 277,
kbdillumtoggle = 278,
kbdillumdown = 279,
kbdillumup = 280,
eject = 281,
sleep = 282,
app1 = 283,
app2 = 284,
audiorewind = 285,
audiofastforward = 286,
softleft = 287,
softright = 288,
call = 289,
endcall = 290,
_,
};
pub const Keycode = enum(i32) {
unknown = 0,
@"return" = '\r',
escape = '\x1b',
backspace = '\x08',
tab = '\t',
space = ' ',
exclaim = '!',
quotedbl = '"',
hash = '#',
percent = '%',
dollar = '$',
ampersand = '&',
quote = '\'',
leftparen = '(',
rightparen = ')',
asterisk = '*',
plus = '+',
comma = ',',
minus = '-',
period = '.',
slash = '/',
@"0" = '0',
@"1" = '1',
@"2" = '2',
@"3" = '3',
@"4" = '4',
@"5" = '5',
@"6" = '6',
@"7" = '7',
@"8" = '8',
@"9" = '9',
colon = ':',
semicolon = ';',
less = '<',
equals = '=',
greater = '>',
question = '?',
at = '@',
leftbracket = '[',
backslash = '\\',
rightbracket = ']',
caret = '^',
underscore = '_',
backquote = '`',
a = 'a',
b = 'b',
c = 'c',
d = 'd',
e = 'e',
f = 'f',
g = 'g',
h = 'h',
i = 'i',
j = 'j',
k = 'k',
l = 'l',
m = 'm',
n = 'n',
o = 'o',
p = 'p',
q = 'q',
r = 'r',
s = 's',
t = 't',
u = 'u',
v = 'v',
w = 'w',
x = 'x',
y = 'y',
z = 'z',
capslock = @enumToInt(Scancode.capslock) | mask,
f1 = @enumToInt(Scancode.f1) | mask,
f2 = @enumToInt(Scancode.f2) | mask,
f3 = @enumToInt(Scancode.f3) | mask,
f4 = @enumToInt(Scancode.f4) | mask,
f5 = @enumToInt(Scancode.f5) | mask,
f6 = @enumToInt(Scancode.f6) | mask,
f7 = @enumToInt(Scancode.f7) | mask,
f8 = @enumToInt(Scancode.f8) | mask,
f9 = @enumToInt(Scancode.f9) | mask,
f10 = @enumToInt(Scancode.f10) | mask,
f11 = @enumToInt(Scancode.f11) | mask,
f12 = @enumToInt(Scancode.f12) | mask,
printscreen = @enumToInt(Scancode.printscreen) | mask,
scrolllock = @enumToInt(Scancode.scrolllock) | mask,
pause = @enumToInt(Scancode.pause) | mask,
insert = @enumToInt(Scancode.insert) | mask,
home = @enumToInt(Scancode.home) | mask,
pageup = @enumToInt(Scancode.pageup) | mask,
delete = '\x7f',
end = @enumToInt(Scancode.end) | mask,
pagedown = @enumToInt(Scancode.pagedown) | mask,
right = @enumToInt(Scancode.right) | mask,
left = @enumToInt(Scancode.left) | mask,
down = @enumToInt(Scancode.down) | mask,
up = @enumToInt(Scancode.up) | mask,
numlockclear = @enumToInt(Scancode.numlockclear) | mask,
kp_divide = @enumToInt(Scancode.kp_divide) | mask,
kp_multiply = @enumToInt(Scancode.kp_multiply) | mask,
kp_minus = @enumToInt(Scancode.kp_minus) | mask,
kp_plus = @enumToInt(Scancode.kp_plus) | mask,
kp_enter = @enumToInt(Scancode.kp_enter) | mask,
kp_1 = @enumToInt(Scancode.kp_1) | mask,
kp_2 = @enumToInt(Scancode.kp_2) | mask,
kp_3 = @enumToInt(Scancode.kp_3) | mask,
kp_4 = @enumToInt(Scancode.kp_4) | mask,
kp_5 = @enumToInt(Scancode.kp_5) | mask,
kp_6 = @enumToInt(Scancode.kp_6) | mask,
kp_7 = @enumToInt(Scancode.kp_7) | mask,
kp_8 = @enumToInt(Scancode.kp_8) | mask,
kp_9 = @enumToInt(Scancode.kp_9) | mask,
kp_0 = @enumToInt(Scancode.kp_0) | mask,
kp_period = @enumToInt(Scancode.kp_period) | mask,
application = @enumToInt(Scancode.application) | mask,
power = @enumToInt(Scancode.power) | mask,
kp_equals = @enumToInt(Scancode.kp_equals) | mask,
f13 = @enumToInt(Scancode.f13) | mask,
f14 = @enumToInt(Scancode.f14) | mask,
f15 = @enumToInt(Scancode.f15) | mask,
f16 = @enumToInt(Scancode.f16) | mask,
f17 = @enumToInt(Scancode.f17) | mask,
f18 = @enumToInt(Scancode.f18) | mask,
f19 = @enumToInt(Scancode.f19) | mask,
f20 = @enumToInt(Scancode.f20) | mask,
f21 = @enumToInt(Scancode.f21) | mask,
f22 = @enumToInt(Scancode.f22) | mask,
f23 = @enumToInt(Scancode.f23) | mask,
f24 = @enumToInt(Scancode.f24) | mask,
execute = @enumToInt(Scancode.execute) | mask,
help = @enumToInt(Scancode.help) | mask,
menu = @enumToInt(Scancode.menu) | mask,
select = @enumToInt(Scancode.select) | mask,
stop = @enumToInt(Scancode.stop) | mask,
again = @enumToInt(Scancode.again) | mask,
undo = @enumToInt(Scancode.undo) | mask,
cut = @enumToInt(Scancode.cut) | mask,
copy = @enumToInt(Scancode.copy) | mask,
paste = @enumToInt(Scancode.paste) | mask,
find = @enumToInt(Scancode.find) | mask,
mute = @enumToInt(Scancode.mute) | mask,
volumeup = @enumToInt(Scancode.volumeup) | mask,
volumedown = @enumToInt(Scancode.volumedown) | mask,
kp_comma = @enumToInt(Scancode.kp_comma) | mask,
kp_equalsas400 = @enumToInt(Scancode.kp_equalsas400) | mask,
alterase = @enumToInt(Scancode.alterase) | mask,
sysreq = @enumToInt(Scancode.sysreq) | mask,
cancel = @enumToInt(Scancode.cancel) | mask,
clear = @enumToInt(Scancode.clear) | mask,
prior = @enumToInt(Scancode.prior) | mask,
return2 = @enumToInt(Scancode.return2) | mask,
separator = @enumToInt(Scancode.separator) | mask,
out = @enumToInt(Scancode.out) | mask,
oper = @enumToInt(Scancode.oper) | mask,
clearagain = @enumToInt(Scancode.clearagain) | mask,
crsel = @enumToInt(Scancode.crsel) | mask,
exsel = @enumToInt(Scancode.exsel) | mask,
kp_00 = @enumToInt(Scancode.kp_00) | mask,
kp_000 = @enumToInt(Scancode.kp_000) | mask,
thousandsseparator = @enumToInt(Scancode.thousandsseparator) | mask,
decimalseparator = @enumToInt(Scancode.decimalseparator) | mask,
currencyunit = @enumToInt(Scancode.currencyunit) | mask,
currencysubunit = @enumToInt(Scancode.currencysubunit) | mask,
kp_leftparen = @enumToInt(Scancode.kp_leftparen) | mask,
kp_rightparen = @enumToInt(Scancode.kp_rightparen) | mask,
kp_leftbrace = @enumToInt(Scancode.kp_leftbrace) | mask,
kp_rightbrace = @enumToInt(Scancode.kp_rightbrace) | mask,
kp_tab = @enumToInt(Scancode.kp_tab) | mask,
kp_backspace = @enumToInt(Scancode.kp_backspace) | mask,
kp_a = @enumToInt(Scancode.kp_a) | mask,
kp_b = @enumToInt(Scancode.kp_b) | mask,
kp_c = @enumToInt(Scancode.kp_c) | mask,
kp_d = @enumToInt(Scancode.kp_d) | mask,
kp_e = @enumToInt(Scancode.kp_e) | mask,
kp_f = @enumToInt(Scancode.kp_f) | mask,
kp_xor = @enumToInt(Scancode.kp_xor) | mask,
kp_power = @enumToInt(Scancode.kp_power) | mask,
kp_percent = @enumToInt(Scancode.kp_percent) | mask,
kp_less = @enumToInt(Scancode.kp_less) | mask,
kp_greater = @enumToInt(Scancode.kp_greater) | mask,
kp_ampersand = @enumToInt(Scancode.kp_ampersand) | mask,
kp_dblampersand = @enumToInt(Scancode.kp_dblampersand) | mask,
kp_verticalbar = @enumToInt(Scancode.kp_verticalbar) | mask,
kp_dblverticalbar = @enumToInt(Scancode.kp_dblverticalbar) | mask,
kp_colon = @enumToInt(Scancode.kp_colon) | mask,
kp_hash = @enumToInt(Scancode.kp_hash) | mask,
kp_space = @enumToInt(Scancode.kp_space) | mask,
kp_at = @enumToInt(Scancode.kp_at) | mask,
kp_exclam = @enumToInt(Scancode.kp_exclam) | mask,
kp_memstore = @enumToInt(Scancode.kp_memstore) | mask,
kp_memrecall = @enumToInt(Scancode.kp_memrecall) | mask,
kp_memclear = @enumToInt(Scancode.kp_memclear) | mask,
kp_memadd = @enumToInt(Scancode.kp_memadd) | mask,
kp_memsubtract = @enumToInt(Scancode.kp_memsubtract) | mask,
kp_memmultiply = @enumToInt(Scancode.kp_memmultiply) | mask,
kp_memdivide = @enumToInt(Scancode.kp_memdivide) | mask,
kp_plusminus = @enumToInt(Scancode.kp_plusminus) | mask,
kp_clear = @enumToInt(Scancode.kp_clear) | mask,
kp_clearentry = @enumToInt(Scancode.kp_clearentry) | mask,
kp_binary = @enumToInt(Scancode.kp_binary) | mask,
kp_octal = @enumToInt(Scancode.kp_octal) | mask,
kp_decimal = @enumToInt(Scancode.kp_decimal) | mask,
kp_hexadecimal = @enumToInt(Scancode.kp_hexadecimal) | mask,
lctrl = @enumToInt(Scancode.lctrl) | mask,
lshift = @enumToInt(Scancode.lshift) | mask,
lalt = @enumToInt(Scancode.lalt) | mask,
lgui = @enumToInt(Scancode.lgui) | mask,
rctrl = @enumToInt(Scancode.rctrl) | mask,
rshift = @enumToInt(Scancode.rshift) | mask,
ralt = @enumToInt(Scancode.ralt) | mask,
rgui = @enumToInt(Scancode.rgui) | mask,
mode = @enumToInt(Scancode.mode) | mask,
audionext = @enumToInt(Scancode.audionext) | mask,
audioprev = @enumToInt(Scancode.audioprev) | mask,
audiostop = @enumToInt(Scancode.audiostop) | mask,
audioplay = @enumToInt(Scancode.audioplay) | mask,
audiomute = @enumToInt(Scancode.audiomute) | mask,
mediaselect = @enumToInt(Scancode.mediaselect) | mask,
www = @enumToInt(Scancode.www) | mask,
mail = @enumToInt(Scancode.mail) | mask,
calculator = @enumToInt(Scancode.calculator) | mask,
computer = @enumToInt(Scancode.computer) | mask,
ac_search = @enumToInt(Scancode.ac_search) | mask,
ac_home = @enumToInt(Scancode.ac_home) | mask,
ac_back = @enumToInt(Scancode.ac_back) | mask,
ac_forward = @enumToInt(Scancode.ac_forward) | mask,
ac_stop = @enumToInt(Scancode.ac_stop) | mask,
ac_refresh = @enumToInt(Scancode.ac_refresh) | mask,
ac_bookmarks = @enumToInt(Scancode.ac_bookmarks) | mask,
brightnessdown = @enumToInt(Scancode.brightnessdown) | mask,
brightnessup = @enumToInt(Scancode.brightnessup) | mask,
displayswitch = @enumToInt(Scancode.displayswitch) | mask,
kbdillumtoggle = @enumToInt(Scancode.kbdillumtoggle) | mask,
kbdillumdown = @enumToInt(Scancode.kbdillumdown) | mask,
kbdillumup = @enumToInt(Scancode.kbdillumup) | mask,
eject = @enumToInt(Scancode.eject) | mask,
sleep = @enumToInt(Scancode.sleep) | mask,
app1 = @enumToInt(Scancode.app1) | mask,
app2 = @enumToInt(Scancode.app2) | mask,
audiorewind = @enumToInt(Scancode.audiorewind) | mask,
audiofastforward = @enumToInt(Scancode.audiofastforward) | mask,
softleft = @enumToInt(Scancode.softleft) | mask,
softright = @enumToInt(Scancode.softright) | mask,
call = @enumToInt(Scancode.call) | mask,
endcall = @enumToInt(Scancode.endcall) | mask,
_,
const mask = 1 << 30;
};
+112 -537
View File
@@ -1,6 +1,10 @@
const std = @import("std");
const assert = std.debug.assert;
//--------------------------------------------------------------------------------------------------
//
// Init
//
//--------------------------------------------------------------------------------------------------
pub const InitFlags = packed struct(u32) {
timer: bool = false,
__unused1: bool = false,
@@ -45,13 +49,16 @@ extern fn SDL_Init(flags: InitFlags) i32;
/// `pub fn quit() void`
pub const quit = SDL_Quit;
extern fn SDL_Quit() void;
//--------------------------------------------------------------------------------------------------
//
// Error
//
//--------------------------------------------------------------------------------------------------
pub fn getError() ?[:0]const u8 {
if (SDL_GetError()) |cstr| {
return std.mem.sliceTo(cstr, 0);
} else {
return null;
if (SDL_GetError()) |ptr| {
return std.mem.sliceTo(ptr, 0);
}
return null;
}
extern fn SDL_GetError() ?[*:0]const u8;
@@ -63,7 +70,55 @@ pub fn makeError() error{SdlError} {
}
return error.SdlError;
}
//--------------------------------------------------------------------------------------------------
//
// Video driver
//
//--------------------------------------------------------------------------------------------------
/// `pub fn getNumVideoDrivers() i32`
pub const getNumVideoDrivers = SDL_GetNumVideoDrivers;
extern fn SDL_GetNumVideoDrivers() i32;
pub fn getVideoDriver(index: i32) ?[:0]const u8 {
if (SDL_GetVideoDriver(index)) |ptr| {
return std.mem.sliceTo(ptr, 0);
}
return null;
}
extern fn SDL_GetVideoDriver(index: i32) ?[*:0]const u8;
//--------------------------------------------------------------------------------------------------
//
// Display
//
//--------------------------------------------------------------------------------------------------
pub const DisplayId = u32;
pub const DisplayMode = DisplayMode_SDL2;
const DisplayMode_SDL2 = extern struct {
format: u32,
w: i32,
h: i32,
refresh_rate: i32,
driverdata: ?*anyopaque,
};
const DisplayMode_SDL3 = extern struct {
display_id: DisplayId,
format: u32,
pixel_w: i32,
pixel_h: i32,
screen_w: i32,
screen_h: i32,
display_scale: f32,
refresh_rate: f32,
driverdata: ?*anyopaque,
};
//--------------------------------------------------------------------------------------------------
//
// Window
//
//--------------------------------------------------------------------------------------------------
pub const Window = opaque {
pub const Flags = packed struct(u32) {
fullscreen: bool = false,
@@ -124,14 +179,22 @@ pub const Window = opaque {
pub const destroy = SDL_DestroyWindow;
extern fn SDL_DestroyWindow(window: *Window) void;
pub fn getDisplayMode(window: *Window) DisplayMode {
pub fn getDisplayMode(window: *Window) Error!DisplayMode {
var mode: DisplayMode = undefined;
SDL_GetWindowDisplayMode(window, &mode);
if (SDL_GetWindowDisplayMode(window, &mode) < 0) return makeError();
return mode;
}
extern fn SDL_GetWindowDisplayMode(*Window, *DisplayMode) void;
};
extern fn SDL_GetWindowDisplayMode(window: *Window, mode: *DisplayMode) void;
/// `pub fn getSize(window: *Window, w: ?*i32, h: ?*i32) void`
pub const getSize = SDL_GetWindowSize;
extern fn SDL_GetWindowSize(window: *Window, w: ?*i32, h: ?*i32) void;
};
//--------------------------------------------------------------------------------------------------
//
// Events
//
//--------------------------------------------------------------------------------------------------
pub const EventType = enum(u32) {
firstevent = 0,
@@ -253,506 +316,9 @@ pub const MouseWheelDirection = enum(u32) {
flipped,
};
pub const Scancode = enum(u32) {
unknown = 0,
a = 4,
b = 5,
c = 6,
d = 7,
e = 8,
f = 9,
g = 10,
h = 11,
i = 12,
j = 13,
k = 14,
l = 15,
m = 16,
n = 17,
o = 18,
p = 19,
q = 20,
r = 21,
s = 22,
t = 23,
u = 24,
v = 25,
w = 26,
x = 27,
y = 28,
z = 29,
@"1" = 30,
@"2" = 31,
@"3" = 32,
@"4" = 33,
@"5" = 34,
@"6" = 35,
@"7" = 36,
@"8" = 37,
@"9" = 38,
@"0" = 39,
@"return" = 40,
escape = 41,
backspace = 42,
tab = 43,
space = 44,
minus = 45,
equals = 46,
leftbracket = 47,
rightbracket = 48,
backslash = 49,
nonushash = 50,
semicolon = 51,
apostrophe = 52,
grave = 53,
comma = 54,
period = 55,
slash = 56,
capslock = 57,
f1 = 58,
f2 = 59,
f3 = 60,
f4 = 61,
f5 = 62,
f6 = 63,
f7 = 64,
f8 = 65,
f9 = 66,
f10 = 67,
f11 = 68,
f12 = 69,
printscreen = 70,
scrolllock = 71,
pause = 72,
insert = 73,
home = 74,
pageup = 75,
delete = 76,
end = 77,
pagedown = 78,
right = 79,
left = 80,
down = 81,
up = 82,
numlockclear = 83,
kp_divide = 84,
kp_multiply = 85,
kp_minus = 86,
kp_plus = 87,
kp_enter = 88,
kp_1 = 89,
kp_2 = 90,
kp_3 = 91,
kp_4 = 92,
kp_5 = 93,
kp_6 = 94,
kp_7 = 95,
kp_8 = 96,
kp_9 = 97,
kp_0 = 98,
kp_period = 99,
nonusbackslash = 100,
application = 101,
power = 102,
kp_equals = 103,
f13 = 104,
f14 = 105,
f15 = 106,
f16 = 107,
f17 = 108,
f18 = 109,
f19 = 110,
f20 = 111,
f21 = 112,
f22 = 113,
f23 = 114,
f24 = 115,
execute = 116,
help = 117,
menu = 118,
select = 119,
stop = 120,
again = 121,
undo = 122,
cut = 123,
copy = 124,
paste = 125,
find = 126,
mute = 127,
volumeup = 128,
volumedown = 129,
kp_comma = 133,
kp_equalsas400 = 134,
international1 = 135,
international2 = 136,
international3 = 137,
international4 = 138,
international5 = 139,
international6 = 140,
international7 = 141,
international8 = 142,
international9 = 143,
lang1 = 144,
lang2 = 145,
lang3 = 146,
lang4 = 147,
lang5 = 148,
lang6 = 149,
lang7 = 150,
lang8 = 151,
lang9 = 152,
alterase = 153,
sysreq = 154,
cancel = 155,
clear = 156,
prior = 157,
return2 = 158,
separator = 159,
out = 160,
oper = 161,
clearagain = 162,
crsel = 163,
exsel = 164,
kp_00 = 176,
kp_000 = 177,
thousandsseparator = 178,
decimalseparator = 179,
currencyunit = 180,
currencysubunit = 181,
kp_leftparen = 182,
kp_rightparen = 183,
kp_leftbrace = 184,
kp_rightbrace = 185,
kp_tab = 186,
kp_backspace = 187,
kp_a = 188,
kp_b = 189,
kp_c = 190,
kp_d = 191,
kp_e = 192,
kp_f = 193,
kp_xor = 194,
kp_power = 195,
kp_percent = 196,
kp_less = 197,
kp_greater = 198,
kp_ampersand = 199,
kp_dblampersand = 200,
kp_verticalbar = 201,
kp_dblverticalbar = 202,
kp_colon = 203,
kp_hash = 204,
kp_space = 205,
kp_at = 206,
kp_exclam = 207,
kp_memstore = 208,
kp_memrecall = 209,
kp_memclear = 210,
kp_memadd = 211,
kp_memsubtract = 212,
kp_memmultiply = 213,
kp_memdivide = 214,
kp_plusminus = 215,
kp_clear = 216,
kp_clearentry = 217,
kp_binary = 218,
kp_octal = 219,
kp_decimal = 220,
kp_hexadecimal = 221,
lctrl = 224,
lshift = 225,
lalt = 226,
lgui = 227,
rctrl = 228,
rshift = 229,
ralt = 230,
rgui = 231,
mode = 257,
audionext = 258,
audioprev = 259,
audiostop = 260,
audioplay = 261,
audiomute = 262,
mediaselect = 263,
www = 264,
mail = 265,
calculator = 266,
computer = 267,
ac_search = 268,
ac_home = 269,
ac_back = 270,
ac_forward = 271,
ac_stop = 272,
ac_refresh = 273,
ac_bookmarks = 274,
brightnessdown = 275,
brightnessup = 276,
displayswitch = 277,
kbdillumtoggle = 278,
kbdillumdown = 279,
kbdillumup = 280,
eject = 281,
sleep = 282,
app1 = 283,
app2 = 284,
audiorewind = 285,
audiofastforward = 286,
softleft = 287,
softright = 288,
call = 289,
endcall = 290,
_,
};
pub const Scancode = @import("keyboard.zig").Scancode;
pub const Keycode = enum(i32) {
unknown = 0,
@"return" = '\r',
escape = '\x1b',
backspace = '\x08',
tab = '\t',
space = ' ',
exclaim = '!',
quotedbl = '"',
hash = '#',
percent = '%',
dollar = '$',
ampersand = '&',
quote = '\'',
leftparen = '(',
rightparen = ')',
asterisk = '*',
plus = '+',
comma = ',',
minus = '-',
period = '.',
slash = '/',
@"0" = '0',
@"1" = '1',
@"2" = '2',
@"3" = '3',
@"4" = '4',
@"5" = '5',
@"6" = '6',
@"7" = '7',
@"8" = '8',
@"9" = '9',
colon = ':',
semicolon = ';',
less = '<',
equals = '=',
greater = '>',
question = '?',
at = '@',
leftbracket = '[',
backslash = '\\',
rightbracket = ']',
caret = '^',
underscore = '_',
backquote = '`',
a = 'a',
b = 'b',
c = 'c',
d = 'd',
e = 'e',
f = 'f',
g = 'g',
h = 'h',
i = 'i',
j = 'j',
k = 'k',
l = 'l',
m = 'm',
n = 'n',
o = 'o',
p = 'p',
q = 'q',
r = 'r',
s = 's',
t = 't',
u = 'u',
v = 'v',
w = 'w',
x = 'x',
y = 'y',
z = 'z',
capslock = @enumToInt(Scancode.capslock) | mask,
f1 = @enumToInt(Scancode.f1) | mask,
f2 = @enumToInt(Scancode.f2) | mask,
f3 = @enumToInt(Scancode.f3) | mask,
f4 = @enumToInt(Scancode.f4) | mask,
f5 = @enumToInt(Scancode.f5) | mask,
f6 = @enumToInt(Scancode.f6) | mask,
f7 = @enumToInt(Scancode.f7) | mask,
f8 = @enumToInt(Scancode.f8) | mask,
f9 = @enumToInt(Scancode.f9) | mask,
f10 = @enumToInt(Scancode.f10) | mask,
f11 = @enumToInt(Scancode.f11) | mask,
f12 = @enumToInt(Scancode.f12) | mask,
printscreen = @enumToInt(Scancode.printscreen) | mask,
scrolllock = @enumToInt(Scancode.scrolllock) | mask,
pause = @enumToInt(Scancode.pause) | mask,
insert = @enumToInt(Scancode.insert) | mask,
home = @enumToInt(Scancode.home) | mask,
pageup = @enumToInt(Scancode.pageup) | mask,
delete = '\x7f',
end = @enumToInt(Scancode.end) | mask,
pagedown = @enumToInt(Scancode.pagedown) | mask,
right = @enumToInt(Scancode.right) | mask,
left = @enumToInt(Scancode.left) | mask,
down = @enumToInt(Scancode.down) | mask,
up = @enumToInt(Scancode.up) | mask,
numlockclear = @enumToInt(Scancode.numlockclear) | mask,
kp_divide = @enumToInt(Scancode.kp_divide) | mask,
kp_multiply = @enumToInt(Scancode.kp_multiply) | mask,
kp_minus = @enumToInt(Scancode.kp_minus) | mask,
kp_plus = @enumToInt(Scancode.kp_plus) | mask,
kp_enter = @enumToInt(Scancode.kp_enter) | mask,
kp_1 = @enumToInt(Scancode.kp_1) | mask,
kp_2 = @enumToInt(Scancode.kp_2) | mask,
kp_3 = @enumToInt(Scancode.kp_3) | mask,
kp_4 = @enumToInt(Scancode.kp_4) | mask,
kp_5 = @enumToInt(Scancode.kp_5) | mask,
kp_6 = @enumToInt(Scancode.kp_6) | mask,
kp_7 = @enumToInt(Scancode.kp_7) | mask,
kp_8 = @enumToInt(Scancode.kp_8) | mask,
kp_9 = @enumToInt(Scancode.kp_9) | mask,
kp_0 = @enumToInt(Scancode.kp_0) | mask,
kp_period = @enumToInt(Scancode.kp_period) | mask,
application = @enumToInt(Scancode.application) | mask,
power = @enumToInt(Scancode.power) | mask,
kp_equals = @enumToInt(Scancode.kp_equals) | mask,
f13 = @enumToInt(Scancode.f13) | mask,
f14 = @enumToInt(Scancode.f14) | mask,
f15 = @enumToInt(Scancode.f15) | mask,
f16 = @enumToInt(Scancode.f16) | mask,
f17 = @enumToInt(Scancode.f17) | mask,
f18 = @enumToInt(Scancode.f18) | mask,
f19 = @enumToInt(Scancode.f19) | mask,
f20 = @enumToInt(Scancode.f20) | mask,
f21 = @enumToInt(Scancode.f21) | mask,
f22 = @enumToInt(Scancode.f22) | mask,
f23 = @enumToInt(Scancode.f23) | mask,
f24 = @enumToInt(Scancode.f24) | mask,
execute = @enumToInt(Scancode.execute) | mask,
help = @enumToInt(Scancode.help) | mask,
menu = @enumToInt(Scancode.menu) | mask,
select = @enumToInt(Scancode.select) | mask,
stop = @enumToInt(Scancode.stop) | mask,
again = @enumToInt(Scancode.again) | mask,
undo = @enumToInt(Scancode.undo) | mask,
cut = @enumToInt(Scancode.cut) | mask,
copy = @enumToInt(Scancode.copy) | mask,
paste = @enumToInt(Scancode.paste) | mask,
find = @enumToInt(Scancode.find) | mask,
mute = @enumToInt(Scancode.mute) | mask,
volumeup = @enumToInt(Scancode.volumeup) | mask,
volumedown = @enumToInt(Scancode.volumedown) | mask,
kp_comma = @enumToInt(Scancode.kp_comma) | mask,
kp_equalsas400 = @enumToInt(Scancode.kp_equalsas400) | mask,
alterase = @enumToInt(Scancode.alterase) | mask,
sysreq = @enumToInt(Scancode.sysreq) | mask,
cancel = @enumToInt(Scancode.cancel) | mask,
clear = @enumToInt(Scancode.clear) | mask,
prior = @enumToInt(Scancode.prior) | mask,
return2 = @enumToInt(Scancode.return2) | mask,
separator = @enumToInt(Scancode.separator) | mask,
out = @enumToInt(Scancode.out) | mask,
oper = @enumToInt(Scancode.oper) | mask,
clearagain = @enumToInt(Scancode.clearagain) | mask,
crsel = @enumToInt(Scancode.crsel) | mask,
exsel = @enumToInt(Scancode.exsel) | mask,
kp_00 = @enumToInt(Scancode.kp_00) | mask,
kp_000 = @enumToInt(Scancode.kp_000) | mask,
thousandsseparator = @enumToInt(Scancode.thousandsseparator) | mask,
decimalseparator = @enumToInt(Scancode.decimalseparator) | mask,
currencyunit = @enumToInt(Scancode.currencyunit) | mask,
currencysubunit = @enumToInt(Scancode.currencysubunit) | mask,
kp_leftparen = @enumToInt(Scancode.kp_leftparen) | mask,
kp_rightparen = @enumToInt(Scancode.kp_rightparen) | mask,
kp_leftbrace = @enumToInt(Scancode.kp_leftbrace) | mask,
kp_rightbrace = @enumToInt(Scancode.kp_rightbrace) | mask,
kp_tab = @enumToInt(Scancode.kp_tab) | mask,
kp_backspace = @enumToInt(Scancode.kp_backspace) | mask,
kp_a = @enumToInt(Scancode.kp_a) | mask,
kp_b = @enumToInt(Scancode.kp_b) | mask,
kp_c = @enumToInt(Scancode.kp_c) | mask,
kp_d = @enumToInt(Scancode.kp_d) | mask,
kp_e = @enumToInt(Scancode.kp_e) | mask,
kp_f = @enumToInt(Scancode.kp_f) | mask,
kp_xor = @enumToInt(Scancode.kp_xor) | mask,
kp_power = @enumToInt(Scancode.kp_power) | mask,
kp_percent = @enumToInt(Scancode.kp_percent) | mask,
kp_less = @enumToInt(Scancode.kp_less) | mask,
kp_greater = @enumToInt(Scancode.kp_greater) | mask,
kp_ampersand = @enumToInt(Scancode.kp_ampersand) | mask,
kp_dblampersand = @enumToInt(Scancode.kp_dblampersand) | mask,
kp_verticalbar = @enumToInt(Scancode.kp_verticalbar) | mask,
kp_dblverticalbar = @enumToInt(Scancode.kp_dblverticalbar) | mask,
kp_colon = @enumToInt(Scancode.kp_colon) | mask,
kp_hash = @enumToInt(Scancode.kp_hash) | mask,
kp_space = @enumToInt(Scancode.kp_space) | mask,
kp_at = @enumToInt(Scancode.kp_at) | mask,
kp_exclam = @enumToInt(Scancode.kp_exclam) | mask,
kp_memstore = @enumToInt(Scancode.kp_memstore) | mask,
kp_memrecall = @enumToInt(Scancode.kp_memrecall) | mask,
kp_memclear = @enumToInt(Scancode.kp_memclear) | mask,
kp_memadd = @enumToInt(Scancode.kp_memadd) | mask,
kp_memsubtract = @enumToInt(Scancode.kp_memsubtract) | mask,
kp_memmultiply = @enumToInt(Scancode.kp_memmultiply) | mask,
kp_memdivide = @enumToInt(Scancode.kp_memdivide) | mask,
kp_plusminus = @enumToInt(Scancode.kp_plusminus) | mask,
kp_clear = @enumToInt(Scancode.kp_clear) | mask,
kp_clearentry = @enumToInt(Scancode.kp_clearentry) | mask,
kp_binary = @enumToInt(Scancode.kp_binary) | mask,
kp_octal = @enumToInt(Scancode.kp_octal) | mask,
kp_decimal = @enumToInt(Scancode.kp_decimal) | mask,
kp_hexadecimal = @enumToInt(Scancode.kp_hexadecimal) | mask,
lctrl = @enumToInt(Scancode.lctrl) | mask,
lshift = @enumToInt(Scancode.lshift) | mask,
lalt = @enumToInt(Scancode.lalt) | mask,
lgui = @enumToInt(Scancode.lgui) | mask,
rctrl = @enumToInt(Scancode.rctrl) | mask,
rshift = @enumToInt(Scancode.rshift) | mask,
ralt = @enumToInt(Scancode.ralt) | mask,
rgui = @enumToInt(Scancode.rgui) | mask,
mode = @enumToInt(Scancode.mode) | mask,
audionext = @enumToInt(Scancode.audionext) | mask,
audioprev = @enumToInt(Scancode.audioprev) | mask,
audiostop = @enumToInt(Scancode.audiostop) | mask,
audioplay = @enumToInt(Scancode.audioplay) | mask,
audiomute = @enumToInt(Scancode.audiomute) | mask,
mediaselect = @enumToInt(Scancode.mediaselect) | mask,
www = @enumToInt(Scancode.www) | mask,
mail = @enumToInt(Scancode.mail) | mask,
calculator = @enumToInt(Scancode.calculator) | mask,
computer = @enumToInt(Scancode.computer) | mask,
ac_search = @enumToInt(Scancode.ac_search) | mask,
ac_home = @enumToInt(Scancode.ac_home) | mask,
ac_back = @enumToInt(Scancode.ac_back) | mask,
ac_forward = @enumToInt(Scancode.ac_forward) | mask,
ac_stop = @enumToInt(Scancode.ac_stop) | mask,
ac_refresh = @enumToInt(Scancode.ac_refresh) | mask,
ac_bookmarks = @enumToInt(Scancode.ac_bookmarks) | mask,
brightnessdown = @enumToInt(Scancode.brightnessdown) | mask,
brightnessup = @enumToInt(Scancode.brightnessup) | mask,
displayswitch = @enumToInt(Scancode.displayswitch) | mask,
kbdillumtoggle = @enumToInt(Scancode.kbdillumtoggle) | mask,
kbdillumdown = @enumToInt(Scancode.kbdillumdown) | mask,
kbdillumup = @enumToInt(Scancode.kbdillumup) | mask,
eject = @enumToInt(Scancode.eject) | mask,
sleep = @enumToInt(Scancode.sleep) | mask,
app1 = @enumToInt(Scancode.app1) | mask,
app2 = @enumToInt(Scancode.app2) | mask,
audiorewind = @enumToInt(Scancode.audiorewind) | mask,
audiofastforward = @enumToInt(Scancode.audiofastforward) | mask,
softleft = @enumToInt(Scancode.softleft) | mask,
softright = @enumToInt(Scancode.softright) | mask,
call = @enumToInt(Scancode.call) | mask,
endcall = @enumToInt(Scancode.endcall) | mask,
_,
const mask = 1 << 30;
};
pub const Keycode = @import("keyboard.zig").Keycode;
pub const Keysym = extern struct {
scancode: Scancode,
@@ -832,7 +398,7 @@ pub const TextInputEvent = extern struct {
pub const MouseMotionEvent = extern struct {
type: EventType,
timestamp: u32,
windowID: u32,
window_id: u32,
which: u32,
state: u32,
x: i32,
@@ -844,7 +410,7 @@ pub const MouseMotionEvent = extern struct {
pub const MouseButtonEvent = extern struct {
type: EventType,
timestamp: u32,
windowID: u32,
window_id: u32,
which: u32,
button: u8,
state: ReleasedOrPressed,
@@ -871,6 +437,13 @@ pub const QuitEvent = extern struct {
timestamp: u32,
};
pub const DropEvent = extern struct {
type: EventType,
timestamp: u32,
file: ?[*:0]u8,
window_id: u32,
};
pub const Event = extern union {
type: EventType,
common: CommonEvent,
@@ -884,6 +457,7 @@ pub const Event = extern union {
button: MouseButtonEvent,
wheel: MouseWheelEvent,
quit: QuitEvent,
drop: DropEvent,
padding: [size]u8,
@@ -899,37 +473,29 @@ pub fn pollEvent(event: ?*Event) bool {
}
extern fn SDL_PollEvent(event: ?*Event) i32;
/// `pub fn getMouseFocus() ?*Window`
pub const getMouseFocus = SDL_GetMouseFocus;
extern fn SDL_GetMouseFocus() ?*Window;
/// `pub fn getMouseState(x: ?*i32, y: ?*i32) u32`
pub const getMouseState = SDL_GetMouseState;
extern fn SDL_GetMouseState(x: ?*i32, y: ?*i32) u32;
//--------------------------------------------------------------------------------------------------
//
// Hints
//
//--------------------------------------------------------------------------------------------------
pub const hint_windows_dpi_awareness = "SDL_WINDOWS_DPI_AWARENESS";
pub fn setHint(name: [:0]const u8, value: [:0]const u8) bool {
return SDL_SetHint(name, value) != 0;
}
extern fn SDL_SetHint(name: [*:0]const u8, value: [*:0]const u8) i32;
pub const DisplayId = u32;
pub const DisplayMode = DisplayMode_SDL2;
const DisplayMode_SDL2 = extern struct {
format: u32,
w: i32,
h: i32,
refresh_rate: i32,
driverdata: *anyopaque,
};
const DisplayMode_SDL3 = extern struct {
display_id: DisplayId,
format: u32,
pixel_w: i32,
pixel_h: i32,
screen_w: i32,
screen_h: i32,
display_scale: f32,
refresh_rate: f32,
driverdata: *anyopaque,
};
//--------------------------------------------------------------------------------------------------
//
// Timer
//
//--------------------------------------------------------------------------------------------------
/// `pub fn getPerformanceCounter() u64`
pub const getPerformanceCounter = SDL_GetPerformanceCounter;
extern fn SDL_GetPerformanceCounter() u64;
@@ -941,7 +507,11 @@ extern fn SDL_GetPerformanceFrequency() u64;
/// `pub fn delay(ms: u32) void`
pub const delay = SDL_Delay;
extern fn SDL_Delay(ms: u32) void;
//--------------------------------------------------------------------------------------------------
//
// OpenGL
//
//--------------------------------------------------------------------------------------------------
pub const gl = struct {
pub const Context = *anyopaque;
@@ -1048,4 +618,9 @@ pub const gl = struct {
/// `pub fn deleteContext(context: Context) void`
pub const deleteContext = SDL_GL_DeleteContext;
extern fn SDL_GL_DeleteContext(context: Context) void;
/// `pub fn getDrawableSize(window: *Window, w: ?*i32, h: ?*i32) void`
pub const getDrawableSize = SDL_GL_GetDrawableSize;
extern fn SDL_GL_GetDrawableSize(window: *Window, w: ?*i32, h: ?*i32) void;
};
//--------------------------------------------------------------------------------------------------
+45 -20
View File
@@ -1,4 +1,4 @@
# zstbi v0.9.2 - stb image bindings
# zstbi v0.9.3 - stb image bindings
## Features
@@ -35,30 +35,55 @@ const zstbi = @import("zstbi");
zstbi.init(allocator);
defer zstbi.deinit();
```
Load image:
```zig
var image = try zstbi.Image.init("data/image.png", num_desired_channels);
pub const Image = struct {
data: []u8,
width: u32,
height: u32,
num_components: u32,
bytes_per_component: u32,
bytes_per_row: u32,
is_hdr: bool,
...
```
```zig
pub fn loadFromFile(pathname: [:0]const u8, forced_num_components: u32) !Image
pub fn loadFromMemory(data: []const u8, forced_num_components: u32) !Image
pub fn createEmpty(width: u32, height: u32, num_components: u32, args: struct {
bytes_per_component: u32 = 0,
bytes_per_row: u32 = 0,
}) !Image
pub fn info(pathname: [:0]const u8) struct {
is_supported: bool,
width: u32,
height: u32,
num_components: u32,
}
pub fn resize(image: *const Image, new_width: u32, new_height: u32) Image
pub fn writeToFile(
image: *const Image,
filename: [:0]const u8,
image_format: ImageWriteFormat,
) ImageWriteError!void
pub fn writeToFn(
image: *const Image,
write_fn: *const fn (ctx: ?*anyopaque, data: ?*anyopaque, size: c_int) callconv(.C) void,
context: ?*anyopaque,
image_format: ImageWriteFormat,
) ImageWriteError!void
```
```zig
var image = try zstbi.Image.loadFromFile("data/image.png", forced_num_components);
defer image.deinit();
_ = image.data; // stored as []u8
_ = image.width;
_ = image.height;
_ = image.num_components;
_ = image.bytes_per_component;
_ = image.bytes_per_row;
_ = image.is_hdr;
const new_resized_image = image.resize(1024, 1024);
```
Get image info without loading:
```zig
const image_info = zstbi.Image.info("data/image.jpg");
_ = image_info.is_supported; // Is image format supported?
_ = image_info.width;
_ = image_info.height;
_ = image_info.num_components;
```
Misc functions:
```zig
pub fn isHdr(filename: [:0]const u8) bool
+117 -27
View File
@@ -1,4 +1,4 @@
/* stb_image - v2.27 - public domain image loader - http://nothings.org/stb
/* stb_image - v2.28 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,6 +48,7 @@ LICENSE
RECENT REVISION HISTORY:
2.28 (2023-01-29) many error fixes, security errors, just tons of stuff
2.27 (2021-07-11) document stbi_info better, 16-bit PNM support, bug fixes
2.26 (2020-07-13) many minor fixes
2.25 (2020-02-02) fix warnings
@@ -108,7 +109,7 @@ RECENT REVISION HISTORY:
Cass Everitt Ryamond Barbiero github:grim210
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
Josh Tobin Matthew Gregan github:poppolopoppo
Josh Tobin Neil Bickford Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
Brad Weinberger Matvey Cherevko github:mosra
@@ -140,7 +141,7 @@ RECENT REVISION HISTORY:
// // ... x = width, y = height, n = # 8-bit components per pixel ...
// // ... replace '0' with '1'..'4' to force that many components per pixel
// // ... but 'n' will always be the number that it would have been if you said 0
// stbi_image_free(data)
// stbi_image_free(data);
//
// Standard parameters:
// int *x -- outputs image width in pixels
@@ -635,7 +636,7 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#endif
#endif
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__SYMBIAN32__)
typedef unsigned short stbi__uint16;
typedef signed short stbi__int16;
typedef unsigned int stbi__uint32;
@@ -1063,6 +1064,23 @@ static void *stbi__malloc_mad4(int a, int b, int c, int d, int add)
}
#endif
// returns 1 if the sum of two signed ints is valid (between -2^31 and 2^31-1 inclusive), 0 on overflow.
static int stbi__addints_valid(int a, int b)
{
if ((a >= 0) != (b >= 0)) return 1; // a and b have different signs, so no overflow
if (a < 0 && b < 0) return a >= INT_MIN - b; // same as a + b >= INT_MIN; INT_MIN - b cannot overflow since b < 0.
return a <= INT_MAX - b;
}
// returns 1 if the product of two signed shorts is valid, 0 on overflow.
static int stbi__mul2shorts_valid(short a, short b)
{
if (b == 0 || b == -1) return 1; // multiplication by 0 is always 0; check for -1 so SHRT_MIN/b doesn't overflow
if ((a >= 0) == (b >= 0)) return a <= SHRT_MAX/b; // product is positive, so similar to mul2sizes_valid
if (b < 0) return a <= SHRT_MIN / b; // same as a * b >= SHRT_MIN
return a >= SHRT_MIN / b;
}
// stbi__err - error
// stbi__errpf - error returning pointer to float
// stbi__errpuc - error returning pointer to unsigned char
@@ -1985,9 +2003,12 @@ static int stbi__build_huffman(stbi__huffman *h, int *count)
int i,j,k=0;
unsigned int code;
// build size list for each symbol (from JPEG spec)
for (i=0; i < 16; ++i)
for (j=0; j < count[i]; ++j)
for (i=0; i < 16; ++i) {
for (j=0; j < count[i]; ++j) {
h->size[k++] = (stbi_uc) (i+1);
if(k >= 257) return stbi__err("bad size list","Corrupt JPEG");
}
}
h->size[k] = 0;
// compute actual symbols (from jpeg spec)
@@ -2112,6 +2133,8 @@ stbi_inline static int stbi__jpeg_huff_decode(stbi__jpeg *j, stbi__huffman *h)
// convert the huffman code to the symbol id
c = ((j->code_buffer >> (32 - k)) & stbi__bmask[k]) + h->delta[k];
if(c < 0 || c >= 256) // symbol id out of bounds!
return -1;
STBI_ASSERT((((j->code_buffer) >> (32 - h->size[c])) & stbi__bmask[h->size[c]]) == h->code[c]);
// convert the id to a symbol
@@ -2130,6 +2153,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
unsigned int k;
int sgn;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
sgn = j->code_buffer >> 31; // sign bit always in MSB; 0 if MSB clear (positive), 1 if MSB set (negative)
k = stbi_lrot(j->code_buffer, n);
@@ -2144,6 +2168,7 @@ stbi_inline static int stbi__jpeg_get_bits(stbi__jpeg *j, int n)
{
unsigned int k;
if (j->code_bits < n) stbi__grow_buffer_unsafe(j);
if (j->code_bits < n) return 0; // ran out of bits from stream, return 0s intead of continuing
k = stbi_lrot(j->code_buffer, n);
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
@@ -2155,6 +2180,7 @@ stbi_inline static int stbi__jpeg_get_bit(stbi__jpeg *j)
{
unsigned int k;
if (j->code_bits < 1) stbi__grow_buffer_unsafe(j);
if (j->code_bits < 1) return 0; // ran out of bits from stream, return 0s intead of continuing
k = j->code_buffer;
j->code_buffer <<= 1;
--j->code_bits;
@@ -2192,8 +2218,10 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
memset(data,0,64*sizeof(data[0]));
diff = t ? stbi__extend_receive(j, t) : 0;
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta","Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
if (!stbi__mul2shorts_valid(dc, dequant[0])) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * dequant[0]);
// decode AC components, see JPEG spec
@@ -2207,6 +2235,7 @@ static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
// decode into unzigzag'd location
@@ -2246,8 +2275,10 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
if (t < 0 || t > 15) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
diff = t ? stbi__extend_receive(j, t) : 0;
if (!stbi__addints_valid(j->img_comp[b].dc_pred, diff)) return stbi__err("bad delta", "Corrupt JPEG");
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
if (!stbi__mul2shorts_valid(dc, 1 << j->succ_low)) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
data[0] = (short) (dc * (1 << j->succ_low));
} else {
// refinement scan for DC coefficient
@@ -2282,6 +2313,7 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
if (r) { // fast-AC path
k += (r >> 4) & 15; // run
s = r & 15; // combined length
if (s > j->code_bits) return stbi__err("bad huffman code", "Combined length longer than code bits available");
j->code_buffer <<= s;
j->code_bits -= s;
zig = stbi__jpeg_dezigzag[k++];
@@ -3102,6 +3134,7 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
sizes[i] = stbi__get8(z->s);
n += sizes[i];
}
if(n > 256) return stbi__err("bad DHT header","Corrupt JPEG"); // Loop over i < n would write past end of values!
L -= 17;
if (tc == 0) {
if (!stbi__build_huffman(z->huff_dc+th, sizes)) return 0;
@@ -3351,6 +3384,28 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
return 1;
}
static int stbi__skip_jpeg_junk_at_end(stbi__jpeg *j)
{
// some JPEGs have junk at end, skip over it but if we find what looks
// like a valid marker, resume there
while (!stbi__at_eof(j->s)) {
int x = stbi__get8(j->s);
while (x == 255) { // might be a marker
if (stbi__at_eof(j->s)) return STBI__MARKER_none;
x = stbi__get8(j->s);
if (x != 0x00 && x != 0xff) {
// not a stuffed zero or lead-in to another marker, looks
// like an actual marker, return it
return x;
}
// stuffed zero has x=0 now which ends the loop, meaning we go
// back to regular scan loop.
// repeated 0xff keeps trying to read the next byte of the marker.
}
}
return STBI__MARKER_none;
}
// decode image to YCbCr format
static int stbi__decode_jpeg_image(stbi__jpeg *j)
{
@@ -3367,25 +3422,22 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
if (!stbi__process_scan_header(j)) return 0;
if (!stbi__parse_entropy_coded_data(j)) return 0;
if (j->marker == STBI__MARKER_none ) {
// handle 0s at the end of image data from IP Kamera 9060
while (!stbi__at_eof(j->s)) {
int x = stbi__get8(j->s);
if (x == 255) {
j->marker = stbi__get8(j->s);
break;
}
}
j->marker = stbi__skip_jpeg_junk_at_end(j);
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
}
m = stbi__get_marker(j);
if (STBI__RESTART(m))
m = stbi__get_marker(j);
} else if (stbi__DNL(m)) {
int Ld = stbi__get16be(j->s);
stbi__uint32 NL = stbi__get16be(j->s);
if (Ld != 4) return stbi__err("bad DNL len", "Corrupt JPEG");
if (NL != j->s->img_y) return stbi__err("bad DNL height", "Corrupt JPEG");
m = stbi__get_marker(j);
} else {
if (!stbi__process_marker(j, m)) return 0;
if (!stbi__process_marker(j, m)) return 1;
m = stbi__get_marker(j);
}
m = stbi__get_marker(j);
}
if (j->progressive)
stbi__jpeg_finish(j);
@@ -3976,6 +4028,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
if (!j) return stbi__errpuc("outofmem", "Out of memory");
memset(j, 0, sizeof(stbi__jpeg));
STBI_NOTUSED(ri);
j->s = s;
stbi__setup_jpeg(j);
@@ -3989,6 +4042,7 @@ static int stbi__jpeg_test(stbi__context *s)
int r;
stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
if (!j) return stbi__err("outofmem", "Out of memory");
memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
stbi__setup_jpeg(j);
r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
@@ -4014,6 +4068,7 @@ static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
int result;
stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
if (!j) return stbi__err("outofmem", "Out of memory");
memset(j, 0, sizeof(stbi__jpeg));
j->s = s;
result = stbi__jpeg_info_raw(j, x, y, comp);
STBI_FREE(j);
@@ -4256,11 +4311,12 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
a->zout = zout;
return 1;
}
if (z >= 286) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, length codes 286 and 287 must not appear in compressed data
z -= 257;
len = stbi__zlength_base[z];
if (stbi__zlength_extra[z]) len += stbi__zreceive(a, stbi__zlength_extra[z]);
z = stbi__zhuffman_decode(a, &a->z_distance);
if (z < 0) return stbi__err("bad huffman code","Corrupt PNG");
if (z < 0 || z >= 30) return stbi__err("bad huffman code","Corrupt PNG"); // per DEFLATE, distance codes 30 and 31 must not appear in compressed data
dist = stbi__zdist_base[z];
if (stbi__zdist_extra[z]) dist += stbi__zreceive(a, stbi__zdist_extra[z]);
if (zout - a->zout_start < dist) return stbi__err("bad dist","Corrupt PNG");
@@ -4955,7 +5011,7 @@ STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert)
static STBI_THREAD_LOCAL int stbi__unpremultiply_on_load_local, stbi__unpremultiply_on_load_set;
static STBI_THREAD_LOCAL int stbi__de_iphone_flag_local, stbi__de_iphone_flag_set;
STBIDEF void stbi__unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
STBIDEF void stbi_set_unpremultiply_on_load_thread(int flag_true_if_should_unpremultiply)
{
stbi__unpremultiply_on_load_local = flag_true_if_should_unpremultiply;
stbi__unpremultiply_on_load_set = 1;
@@ -5064,14 +5120,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!pal_img_n) {
s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0);
if ((1 << 30) / s->img_x / s->img_n < s->img_y) return stbi__err("too large", "Image too large to decode");
if (scan == STBI__SCAN_header) return 1;
} else {
// if paletted, then pal_n is our final components, and
// img_n is # components to decompress/filter.
s->img_n = 1;
if ((1 << 30) / s->img_x / 4 < s->img_y) return stbi__err("too large","Corrupt PNG");
// if SCAN_header, have to scan to see if we have a tRNS
}
// even with SCAN_header, have to scan to see if we have a tRNS
break;
}
@@ -5103,6 +5158,8 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
has_trans = 1;
// non-paletted with tRNS = constant alpha. if header-scanning, we can stop now.
if (scan == STBI__SCAN_header) { ++s->img_n; return 1; }
if (z->depth == 16) {
for (k = 0; k < s->img_n; ++k) tc16[k] = (stbi__uint16)stbi__get16be(s); // copy the values as-is
} else {
@@ -5115,7 +5172,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
case STBI__PNG_TYPE('I','D','A','T'): {
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
if (scan == STBI__SCAN_header) {
// header scan definitely stops at first IDAT
if (pal_img_n)
s->img_n = pal_img_n;
return 1;
}
if (c.length > (1u << 30)) return stbi__err("IDAT size limit", "IDAT section larger than 2^30 bytes");
if ((int)(ioff + c.length) < (int)ioff) return 0;
if (ioff + c.length > idata_limit) {
stbi__uint32 idata_limit_old = idata_limit;
@@ -5498,8 +5561,22 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - info.extra_read - info.hsz) >> 2;
}
if (psize == 0) {
if (info.offset != s->callback_already_read + (s->img_buffer - s->img_buffer_original)) {
return stbi__errpuc("bad offset", "Corrupt BMP");
// accept some number of extra bytes after the header, but if the offset points either to before
// the header ends or implies a large amount of extra data, reject the file as malformed
int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original);
int header_limit = 1024; // max we actually read is below 256 bytes currently.
int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size.
if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) {
return stbi__errpuc("bad header", "Corrupt BMP");
}
// we established that bytes_read_so_far is positive and sensible.
// the first half of this test rejects offsets that are either too small positives, or
// negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn
// ensures the number computed in the second half of the test can't overflow.
if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) {
return stbi__errpuc("bad offset", "Corrupt BMP");
} else {
stbi__skip(s, info.offset - bytes_read_so_far);
}
}
@@ -7187,12 +7264,12 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
// Run
value = stbi__get8(s);
count -= 128;
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = value;
} else {
// Dump
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
if ((count == 0) || (count > nleft)) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
for (z = 0; z < count; ++z)
scanline[i++ * 4 + k] = stbi__get8(s);
}
@@ -7446,10 +7523,17 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
out = (stbi_uc *) stbi__malloc_mad4(s->img_n, s->img_x, s->img_y, ri->bits_per_channel / 8, 0);
if (!out) return stbi__errpuc("outofmem", "Out of memory");
stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8));
if (!stbi__getn(s, out, s->img_n * s->img_x * s->img_y * (ri->bits_per_channel / 8))) {
STBI_FREE(out);
return stbi__errpuc("bad PNM", "PNM file truncated");
}
if (req_comp && req_comp != s->img_n) {
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
if (ri->bits_per_channel == 16) {
out = (stbi_uc *) stbi__convert_format16((stbi__uint16 *) out, s->img_n, req_comp, s->img_x, s->img_y);
} else {
out = stbi__convert_format(out, s->img_n, req_comp, s->img_x, s->img_y);
}
if (out == NULL) return out; // stbi__convert_format frees input on failure
}
return out;
@@ -7486,6 +7570,8 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
while (!stbi__at_eof(s) && stbi__pnm_isdigit(*c)) {
value = value*10 + (*c - '0');
*c = (char) stbi__get8(s);
if((value > 214748364) || (value == 214748364 && *c > '7'))
return stbi__err("integer parse overflow", "Parsing an integer in the PPM header overflowed a 32-bit int");
}
return value;
@@ -7516,9 +7602,13 @@ static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
stbi__pnm_skip_whitespace(s, &c);
*x = stbi__pnm_getinteger(s, &c); // read width
if(*x == 0)
return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
*y = stbi__pnm_getinteger(s, &c); // read height
if (*y == 0)
return stbi__err("invalid width", "PPM image header had zero or overflowing width");
stbi__pnm_skip_whitespace(s, &c);
maxv = stbi__pnm_getinteger(s, &c); // read max value
+52 -23
View File
@@ -1,4 +1,4 @@
pub const version = @import("std").SemanticVersion{ .major = 0, .minor = 9, .patch = 2 };
pub const version = @import("std").SemanticVersion{ .major = 0, .minor = 9, .patch = 3 };
const std = @import("std");
const assert = std.debug.assert;
@@ -68,7 +68,7 @@ pub const Image = struct {
};
}
pub fn init(pathname: [:0]const u8, forced_num_channels: u32) !Image {
pub fn loadFromFile(pathname: [:0]const u8, forced_num_components: u32) !Image {
var width: u32 = 0;
var height: u32 = 0;
var num_components: u32 = 0;
@@ -85,11 +85,11 @@ pub const Image = struct {
&x,
&y,
&ch,
@intCast(c_int, forced_num_channels),
@intCast(c_int, forced_num_components),
);
if (ptr == null) return error.ImageInitFailed;
num_components = if (forced_num_channels == 0) @intCast(u32, ch) else forced_num_channels;
num_components = if (forced_num_components == 0) @intCast(u32, ch) else forced_num_components;
width = @intCast(u32, x);
height = @intCast(u32, y);
bytes_per_component = 2;
@@ -114,17 +114,17 @@ pub const Image = struct {
&x,
&y,
&ch,
@intCast(c_int, forced_num_channels),
@intCast(c_int, forced_num_components),
)) else stbi_load(
pathname,
&x,
&y,
&ch,
@intCast(c_int, forced_num_channels),
@intCast(c_int, forced_num_components),
);
if (ptr == null) return error.ImageInitFailed;
num_components = if (forced_num_channels == 0) @intCast(u32, ch) else forced_num_channels;
num_components = if (forced_num_components == 0) @intCast(u32, ch) else forced_num_components;
width = @intCast(u32, x);
height = @intCast(u32, y);
bytes_per_component = if (is_16bit) 2 else 1;
@@ -145,7 +145,7 @@ pub const Image = struct {
};
}
pub fn initFromData(data: []const u8, forced_num_channels: u32) !Image {
pub fn loadFromMemory(data: []const u8, forced_num_components: u32) !Image {
// TODO: Add support for HDR images (https://github.com/michal-z/zig-gamedev/issues/155).
var width: u32 = 0;
var height: u32 = 0;
@@ -163,11 +163,11 @@ pub const Image = struct {
&x,
&y,
&ch,
@intCast(c_int, forced_num_channels),
@intCast(c_int, forced_num_components),
);
if (ptr == null) return error.ImageInitFailed;
num_components = if (forced_num_channels == 0) @intCast(u32, ch) else forced_num_channels;
num_components = if (forced_num_components == 0) @intCast(u32, ch) else forced_num_components;
width = @intCast(u32, x);
height = @intCast(u32, y);
bytes_per_component = 1;
@@ -187,6 +187,32 @@ pub const Image = struct {
};
}
pub fn createEmpty(width: u32, height: u32, num_components: u32, args: struct {
bytes_per_component: u32 = 0,
bytes_per_row: u32 = 0,
}) !Image {
const bytes_per_component = if (args.bytes_per_component == 0) 1 else args.bytes_per_component;
const bytes_per_row = if (args.bytes_per_row == 0)
width * num_components * bytes_per_component
else
args.bytes_per_row;
const size = height * bytes_per_row;
const data = @ptrCast([*]u8, zstbiMalloc(size));
@memset(data, 0, size);
return Image{
.data = data[0..size],
.width = width,
.height = height,
.num_components = num_components,
.bytes_per_component = bytes_per_component,
.bytes_per_row = bytes_per_row,
.is_hdr = false,
};
}
pub fn resize(image: *const Image, new_width: u32, new_height: u32) Image {
// TODO: Add support for HDR images
const new_bytes_per_row = new_width * image.num_components * image.bytes_per_component;
@@ -215,21 +241,21 @@ pub const Image = struct {
}
pub fn writeToFile(
self: *const Image,
image: *const Image,
filename: [:0]const u8,
image_format: ImageWriteFormat,
) ImageWriteError!void {
const w = @intCast(c_int, self.width);
const h = @intCast(c_int, self.height);
const comp = @intCast(c_int, self.num_components);
const w = @intCast(c_int, image.width);
const h = @intCast(c_int, image.height);
const comp = @intCast(c_int, image.num_components);
const result = switch (image_format) {
.png => stbi_write_png(filename.ptr, w, h, comp, self.data.ptr, 0),
.png => stbi_write_png(filename.ptr, w, h, comp, image.data.ptr, 0),
.jpg => |settings| stbi_write_jpg(
filename.ptr,
w,
h,
comp,
self.data.ptr,
image.data.ptr,
@intCast(c_int, settings.quality),
),
};
@@ -240,23 +266,23 @@ pub const Image = struct {
}
pub fn writeToFn(
self: *const Image,
write_fn: *const fn (?*anyopaque, ?*anyopaque, c_int) callconv(.C) void,
image: *const Image,
write_fn: *const fn (ctx: ?*anyopaque, data: ?*anyopaque, size: c_int) callconv(.C) void,
context: ?*anyopaque,
image_format: ImageWriteFormat,
) ImageWriteError!void {
const w = @intCast(c_int, self.width);
const h = @intCast(c_int, self.height);
const comp = @intCast(c_int, self.num_components);
const w = @intCast(c_int, image.width);
const h = @intCast(c_int, image.height);
const comp = @intCast(c_int, image.num_components);
const result = switch (image_format) {
.png => stbi_write_png_to_func(write_fn, context, w, h, comp, self.data.ptr, 0),
.png => stbi_write_png_to_func(write_fn, context, w, h, comp, image.data.ptr, 0),
.jpg => |settings| stbi_write_jpg_to_func(
write_fn,
context,
w,
h,
comp,
self.data.ptr,
image.data.ptr,
@intCast(c_int, settings.quality),
),
};
@@ -469,4 +495,7 @@ extern fn stbi_write_jpg_to_func(
test "zstbi.basic" {
init(std.testing.allocator);
defer deinit();
var image = try Image.createEmpty(64, 64, 4, .{});
defer image.deinit();
}
+3 -3
View File
@@ -445,12 +445,12 @@ pub const RESOURCE_TRANSITION_BARRIER = extern struct {
};
pub const RESOURCE_ALIASING_BARRIER = extern struct {
pResourceBefore: *IResource,
pResourceAfter: *IResource,
pResourceBefore: ?*IResource,
pResourceAfter: ?*IResource,
};
pub const RESOURCE_UAV_BARRIER = extern struct {
pResource: *IResource,
pResource: ?*IResource,
};
pub const RESOURCE_BARRIER_FLAGS = packed struct(UINT) {
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e7adfbbafa5714a2a9ec3a651c63a4184b2ffff1a3d5c69f5bf402f50cc056ad
size 2796344
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:590cd1fd50cf09e0577d4c1f3cf3d222d4379687e4bdd7d8719fd71e6c5bf708
size 5592580
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ea9d1f7caecc8bd786bc7b5ce607ee31220439f7d36e7b182c34519386102966
size 5592580
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c54dab8e810b9e0e655351f9370cfda23114104c9671229059401c7887857f79
size 5592560
+72 -13
View File
@@ -51,13 +51,21 @@ comptime {
assert(@alignOf([2]Vertex) == 4);
}
// In this demo program, Mesh is just a range of vertices/indices in a single global vertex/index buffer.
const Mesh = struct {
// In this demo program, MeshLod is a range of indices in a single global index buffer.
// A Mesh is an vertex offset into a single global vertex buffer and has a list of lods.
const MeshLod = struct {
index_offset: u32,
vertex_offset: u32,
num_indices: u32,
};
const max_num_lods: u32 = 4;
const Mesh = struct {
vertex_offset: u32,
num_lods: u32,
lods: [max_num_lods]MeshLod,
};
const Scene_Const = extern struct {
world_to_clip: Mat4,
camera_position: Vec3,
@@ -110,6 +118,7 @@ const DemoState = struct {
brdf_integration_texture: ResourceView,
draw_mode: i32,
current_lod: i32,
camera: struct {
position: Vec3,
@@ -129,6 +138,7 @@ fn loadMesh(
all_meshes: *std.ArrayList(Mesh),
all_vertices: *std.ArrayList(Vertex),
all_indices: *std.ArrayList(u32),
generate_lods: u32,
) !void {
var indices = std.ArrayList(u32).init(arena);
var positions = std.ArrayList([3]f32).init(arena);
@@ -148,11 +158,57 @@ fn loadMesh(
defer zmesh.io.freeData(data);
try zmesh.io.appendMeshPrimitive(data, 0, 0, &indices, &positions, &normals, &texcoords0, &tangents);
all_meshes.append(.{
.index_offset = @intCast(u32, pre_indices_len),
var mesh = Mesh{
.vertex_offset = @intCast(u32, pre_positions_len),
.num_indices = @intCast(u32, indices.items.len - pre_indices_len),
}) catch unreachable;
.num_lods = 1,
.lods = undefined,
};
mesh.lods[0] = .{
.index_offset = @intCast(u32, pre_indices_len),
.num_indices = @intCast(u32, indices.items.len),
};
if (generate_lods > 0) {
assert(generate_lods <= max_num_lods);
var all_lods_indices = std.ArrayList(u32).init(arena);
var lod_index: u32 = 1;
while (lod_index < generate_lods) : (lod_index += 1) {
mesh.num_lods += 1;
const threshold: f32 = 1.0 - @intToFloat(f32, lod_index) / @intToFloat(f32, max_num_lods);
const target_index_count: usize = @floatToInt(usize, @intToFloat(f32, indices.items.len) * threshold);
const target_error: f32 = 1e-2;
var lod_indices = std.ArrayList(u32).init(arena);
lod_indices.resize(indices.items.len) catch unreachable;
var lod_error: f32 = 0.0;
var lod_indices_count = zmesh.opt.simplifySloppy(
[3]f32,
lod_indices.items,
indices.items,
indices.items.len,
positions.items,
positions.items.len,
target_index_count,
target_error,
&lod_error,
);
lod_indices.resize(lod_indices_count) catch unreachable;
mesh.lods[lod_index] = .{
.index_offset = mesh.lods[lod_index - 1].index_offset + mesh.lods[lod_index - 1].num_indices,
.num_indices = @intCast(u32, lod_indices_count),
};
all_lods_indices.appendSlice(lod_indices.items) catch unreachable;
}
indices.appendSlice(all_lods_indices.items) catch unreachable;
}
all_meshes.append(mesh) catch unreachable;
try all_indices.ensureTotalCapacity(indices.items.len);
for (indices.items) |mesh_index| {
@@ -370,13 +426,14 @@ fn init(allocator: std.mem.Allocator) !DemoState {
var all_vertices = std.ArrayList(Vertex).init(arena_allocator);
var all_indices = std.ArrayList(u32).init(arena_allocator);
try loadMesh(arena_allocator, content_dir ++ "cube.gltf", &all_meshes, &all_vertices, &all_indices);
try loadMesh(arena_allocator, content_dir ++ "cube.gltf", &all_meshes, &all_vertices, &all_indices, 0);
try loadMesh(
arena_allocator,
content_dir ++ "SciFiHelmet/SciFiHelmet.gltf",
&all_meshes,
&all_vertices,
&all_indices,
max_num_lods,
);
const depth_texture = .{
@@ -463,7 +520,7 @@ fn init(allocator: std.mem.Allocator) !DemoState {
content_dir ++ "Newport_Loft.hdr",
}) catch unreachable;
var image = zstbi.Image.init(pathname, 4) catch unreachable;
var image = zstbi.Image.loadFromFile(pathname, 4) catch unreachable;
defer {
image.deinit();
zstbi.setFlipVerticallyOnLoad(false);
@@ -835,6 +892,7 @@ fn init(allocator: std.mem.Allocator) !DemoState {
.vertex_buffer = vertex_buffer,
.index_buffer = index_buffer,
.draw_mode = 0,
.current_lod = 0,
.camera = .{
.position = Vec3.init(2.2, 0.0, 2.2),
.forward = Vec3.initZero(),
@@ -879,6 +937,7 @@ fn update(demo: *DemoState) void {
_ = c.igRadioButton_IntPtr("Draw Metallic texture", &demo.draw_mode, 3);
_ = c.igRadioButton_IntPtr("Draw Roughness texture", &demo.draw_mode, 4);
_ = c.igRadioButton_IntPtr("Draw Normal texture", &demo.draw_mode, 5);
_ = c.igSliderInt("SciFi Helmet LOD", &demo.current_lod, 0, max_num_lods - 1, "%d", 0);
c.igEnd();
// Handle camera rotation with mouse.
@@ -1007,9 +1066,9 @@ fn draw(demo: *DemoState) void {
});
gctx.cmdlist.DrawIndexedInstanced(
demo.meshes.items[mesh_helmet].num_indices,
demo.meshes.items[mesh_helmet].lods[@intCast(usize, demo.current_lod)].num_indices,
1,
demo.meshes.items[mesh_helmet].index_offset,
demo.meshes.items[mesh_helmet].lods[@intCast(usize, demo.current_lod)].index_offset,
@intCast(i32, demo.meshes.items[mesh_helmet].vertex_offset),
0,
);
@@ -1027,9 +1086,9 @@ fn draw(demo: *DemoState) void {
gctx.cmdlist.SetGraphicsRootDescriptorTable(1, gctx.copyDescriptorsToGpuHeap(1, demo.env_texture.view));
gctx.cmdlist.DrawIndexedInstanced(
demo.meshes.items[mesh_cube].num_indices,
demo.meshes.items[mesh_cube].lods[0].num_indices,
1,
demo.meshes.items[mesh_cube].index_offset,
demo.meshes.items[mesh_cube].lods[0].index_offset,
@intCast(i32, demo.meshes.items[mesh_cube].vertex_offset),
0,
);
+1 -1
View File
@@ -30,7 +30,7 @@ fn create(allocator: std.mem.Allocator, window: *zglfw.Window) !*DemoState {
zstbi.init(arena);
defer zstbi.deinit();
var image = try zstbi.Image.init(content_dir ++ "genart_0025_5.png", 4);
var image = try zstbi.Image.loadFromFile(content_dir ++ "genart_0025_5.png", 4);
defer image.deinit();
// Create a texture.
+11
View File
@@ -33,6 +33,17 @@ pub fn main() !void {
try gl.loadCoreProfile(sdl.gl.getProcAddress, gl_major, gl_minor);
{
var w: i32 = undefined;
var h: i32 = undefined;
window.getSize(&w, &h);
std.debug.print("Window size is {d}x{d}\n", .{ w, h });
sdl.gl.getDrawableSize(window, &w, &h);
std.debug.print("Drawable size is {d}x{d}\n", .{ w, h });
}
main_loop: while (true) {
var event: sdl.Event = undefined;
while (sdl.pollEvent(&event)) {
@@ -244,7 +244,7 @@ fn create(allocator: std.mem.Allocator, window: *zglfw.Window) !*DemoState {
var mesh_texv: [num_mesh_textures]zgpu.TextureViewHandle = undefined;
for (mesh_texture_paths, 0..) |path, tex_index| {
var image = try zstbi.Image.init(path, 4);
var image = try zstbi.Image.loadFromFile(path, 4);
defer image.deinit();
mesh_tex[tex_index] = gctx.createTexture(.{
@@ -808,7 +808,7 @@ fn precomputeImageLighting(
content_dir ++ "freight_station_4k.hdr",
};
zstbi.setFlipVerticallyOnLoad(true);
var image = zstbi.Image.init(
var image = zstbi.Image.loadFromFile(
hdri_paths[@intCast(usize, demo.current_hdri_index)],
4,
) catch unreachable;
@@ -109,7 +109,7 @@ fn create(allocator: std.mem.Allocator, window: *zglfw.Window) !*DemoState {
zstbi.init(arena);
defer zstbi.deinit();
var image = try zstbi.Image.init(content_dir ++ "genart_0025_5.png", 4);
var image = try zstbi.Image.loadFromFile(content_dir ++ "genart_0025_5.png", 4);
defer image.deinit();
// Create a texture.