aboutsummaryrefslogtreecommitdiff
path: root/src/egl.zig
diff options
context:
space:
mode:
authorYaroslav de la Peña Smirnov <yps@yaroslavps.com>2024-09-18 00:02:33 +0300
committerYaroslav de la Peña Smirnov <yps@yaroslavps.com>2024-09-21 18:06:33 +0300
commit5b1d5fc0325dc5e20ccb7b1ce445721762256848 (patch)
tree89e8eaa3dcecfb62a776371319bc6a3bbcf9ee06 /src/egl.zig
parent65b93e57a8caac901348d373bf49df3ebb509984 (diff)
downloadzigway-5b1d5fc0325dc5e20ccb7b1ce445721762256848.tar.gz
zigway-5b1d5fc0325dc5e20ccb7b1ce445721762256848.zip
opengl: triangle
OpenGL hello world triangle on Wayland.
Diffstat (limited to 'src/egl.zig')
-rw-r--r--src/egl.zig186
1 files changed, 186 insertions, 0 deletions
diff --git a/src/egl.zig b/src/egl.zig
new file mode 100644
index 0000000..ad5be7c
--- /dev/null
+++ b/src/egl.zig
@@ -0,0 +1,186 @@
+const c = @cImport({
+ @cInclude("EGL/egl.h");
+ @cInclude("GL/gl.h");
+});
+
+pub const Error = error{
+ Unknown,
+ NoDisplay,
+ NotInitialized,
+ BadAccess,
+ BadAlloc,
+ BadAttribute,
+ BadContext,
+ BadConfig,
+ BadCurrentSurface,
+ BadDisplay,
+ BadMatch,
+ BadNativePixmap,
+ BadNativeWindow,
+ BadParameter,
+ BadSurface,
+ ContextLost,
+};
+
+extern fn eglGetError() i32;
+fn getError() Error!void {
+ return switch (eglGetError()) {
+ c.EGL_NOT_INITIALIZED => Error.NotInitialized,
+ c.EGL_BAD_ACCESS => Error.BadDisplay,
+ c.EGL_BAD_ATTRIBUTE => Error.BadAttribute,
+ c.EGL_BAD_CONFIG => Error.BadConfig,
+ c.EGL_BAD_CONTEXT => Error.BadContext,
+ c.EGL_BAD_CURRENT_SURFACE => Error.BadCurrentSurface,
+ c.EGL_BAD_DISPLAY => Error.BadDisplay,
+ c.EGL_BAD_MATCH => Error.BadMatch,
+ c.EGL_BAD_NATIVE_PIXMAP => Error.BadNativePixmap,
+ c.EGL_BAD_NATIVE_WINDOW => Error.BadNativeWindow,
+ c.EGL_BAD_PARAMETER => Error.BadParameter,
+ c.EGL_BAD_SURFACE => Error.BadSurface,
+ c.EGL_CONTEXT_LOST => Error.ContextLost,
+ else => Error.Unknown,
+ };
+}
+
+pub const Api = enum(u32) {
+ opengl = c.EGL_OPENGL_API,
+ opengl_es = c.EGL_OPENGL_ES_API,
+};
+
+extern fn eglBindAPI(api: Api) bool;
+pub fn bindApi(api: Api) Error!void {
+ if (!eglBindAPI(api)) try getError();
+}
+
+pub const AttributeType = enum(i32) {
+ none = c.EGL_NONE,
+ alpha_size = c.EGL_ALPHA_SIZE,
+ red_size = c.EGL_RED_SIZE,
+ green_size = c.EGL_GREEN_SIZE,
+ blue_size = c.EGL_BLUE_SIZE,
+};
+
+pub const Attribute = packed struct {
+ type: AttributeType,
+ value: i32,
+};
+
+pub const Config = opaque {};
+
+pub const Surface = opaque {};
+
+pub const Context = opaque {};
+
+pub const Display = opaque {
+ extern fn eglGetDisplay(native_display: *anyopaque) ?*Display;
+ pub fn get(native_display: *anyopaque) Error!*Display {
+ return eglGetDisplay(
+ native_display,
+ ) orelse Error.NoDisplay;
+ }
+
+ extern fn eglInitialize(display: *Display, major: ?*i32, minor: ?*i32) bool;
+ pub fn initialize(display: *Display, major: ?*i32, minor: ?*i32) Error!void {
+ if (!eglInitialize(display, major, minor)) try getError();
+ }
+
+ extern fn eglChooseConfig(
+ display: *Display,
+ attributes: [*c]Attribute,
+ configs: [*c]*Config,
+ configs_len: i32,
+ config_cnt: *i32,
+ ) bool;
+ /// Returns the number of configs that were put in @configs.
+ pub fn chooseConfig(
+ display: *Display,
+ attributes: []Attribute,
+ configs: []*Config,
+ ) Error!i32 {
+ var config_cnt: i32 = 0;
+ if (!eglChooseConfig(
+ display,
+ attributes.ptr,
+ configs.ptr,
+ @intCast(configs.len),
+ &config_cnt,
+ )) {
+ try getError();
+ }
+ return config_cnt;
+ }
+
+ extern fn eglCreateContext(
+ display: *Display,
+ config: *Config,
+ share_ctx: ?*Context,
+ attributes: [*c]Attribute,
+ ) ?*Context;
+ pub fn createContext(
+ display: *Display,
+ config: *Config,
+ share_ctx: ?*Context,
+ attributes: ?[]Attribute,
+ ) Error!*Context {
+ var attrs: [*c]Attribute = null;
+ if (attributes) |_attrs| attrs = _attrs.ptr;
+ return eglCreateContext(display, config, share_ctx, attrs) orelse {
+ try getError();
+ unreachable;
+ };
+ }
+
+ extern fn eglCreateWindowSurface(
+ display: *Display,
+ config: *Config,
+ native_window: *anyopaque,
+ attributes: [*c]Attribute,
+ ) ?*Surface;
+ pub fn createWindowSurface(
+ display: *Display,
+ config: *Config,
+ native_window: *anyopaque,
+ attributes: ?[]Attribute,
+ ) Error!*Surface {
+ var attrs: [*c]Attribute = null;
+ if (attributes) |_attrs| attrs = _attrs.ptr;
+ return eglCreateWindowSurface(display, config, native_window, attrs) orelse {
+ try getError();
+ unreachable;
+ };
+ }
+
+ extern fn eglMakeCurrent(
+ display: *Display,
+ draw: *Surface,
+ read: *Surface,
+ ctx: *Context,
+ ) bool;
+ pub fn makeCurrent(
+ display: *Display,
+ draw: *Surface,
+ read: *Surface,
+ ctx: *Context,
+ ) Error!void {
+ if (!eglMakeCurrent(display, draw, read, ctx)) try getError();
+ }
+
+ extern fn eglQueryString(display: *Display, name: i32) [*:0]const u8;
+ pub const queryString = eglQueryString;
+
+ extern fn eglSwapBuffers(display: *Display, surface: *Surface) bool;
+ pub fn swapBuffers(display: *Display, surface: *Surface) Error!void {
+ if (!eglSwapBuffers(display, surface)) try getError();
+ }
+
+ extern fn eglSwapInterval(display: *Display, interval: i32) bool;
+ pub fn swapInterval(display: *Display, interval: i32) Error!void {
+ if (!eglSwapInterval(display, interval)) try getError();
+ }
+
+ extern fn eglTerminate(display: *Display) bool;
+ pub fn terminate(display: *Display) void {
+ // Do I really care if destruction fails?
+ _ = eglTerminate(display);
+ }
+};