--- /dev/null
+{
+ "dark_background": [ 0.1, 0.1, 0.1 ],
+ "background": [ 0.15, 0.15, 0.15 ],
+ "foreground": [ 0.9, 0.9, 0.9 ],
+
+ "keyword": [ 0.7, 0.7, 1.0 ],
+ "value": [ 0.8, 1.0, 0.8 ],
+ "jumppoint": [ 1, 0.5, 0.5 ],
+
+ "primary": [ 0.051, 0.278, 0.631 ],
+ "primary_light": [ 0.329, 0.451, 0.827 ],
+ "primary_dark": [ 0, 0.129, 0.443 ],
+ "primary_text": [ 1, 1, 1 ],
+
+ "secondary": [ 0, 0.376, 0.392 ],
+ "secondary_light": [ 0.259, 0.557, 0.573 ],
+ "secondary_dark": [ 0, 0.212, 0.227 ],
+ "secondary_text": [ 1, 1, 1 ]
+}
--- /dev/null
+#!/bin/sh
+
+$(which python) -m http.server
\ No newline at end of file
gl.bindBuffer(target, buffers[buffer]);
}
},
- bindFramebuffer(target, framebuffer) { gl.bindFramebuffer(target, framebuffers[framebuffer]); },
- bindRenderbuffer(target, renderbuffer) { gl.bindRenderbuffer(target, renderbuffers[renderbuffer]); },
- bindTexture(target, texture) { gl.bindTexture(target, textures[texture]); },
- bindVertexArray(vertexArray) { gl.bindVertexArray(vertexArrays[vertexArray]); },
+ bindFramebuffer(target, framebuffer) {
+ if (framebuffer == -1) {
+ gl.bindFramebuffer(target, null);
+ } else {
+ gl.bindFramebuffer(target, framebuffers[framebuffer]);
+ }
+ },
+ bindRenderbuffer(target, renderbuffer) {
+ if (renderbuffer == -1) {
+ gl.bindRenderbuffer(target, null);
+ } else {
+ gl.bindRenderbuffer(target, renderbuffers[renderbuffer]);
+ }
+ },
+ bindTexture(target, texture) {
+ if (texture == -1) {
+ gl.bindTexture(target, null);
+ } else {
+ gl.bindTexture(target, textures[texture]);
+ }
+ },
+ bindVertexArray(vertexArray) {
+ if (vertexArray == -1) {
+ gl.bindVertexArray(null);
+ } else {
+ gl.bindVertexArray(vertexArrays[vertexArray]);
+ }
+ },
blendColor(red, green, blue, alpha) { gl.blendColor(red, green, blue, alpha); },
blendEquation(mode) { gl.blendEquation(mode); },
canvas.width = width;
canvas.height = height;
},
- checkFrameBufferStatus(target) { return gl.checkFrameBufferStatus(target); },
+ checkFramebufferStatus(target) { return gl.checkFramebufferStatus(target); },
clear(bit) { gl.clear(bit); },
clearColor(r, g, b, a) { gl.clearColor(r, g, b, a); },
clearDepth(depth) { gl.clearDepth(depth); },
gl.compressedSubTexImage2D(target, level, internalformat, xoff, yoff, width, height, format, pixels);
},
copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) { gl.copyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size); },
- copyTexImage2D(target, level, internalforamt, x, y, width, height, border) {
- gl.copyTexImage2D(target, level, internalforamt, x, y, width, height, border);
+ copyTexImage2D(target, level, internalformat, x, y, width, height, border) {
+ gl.copyTexImage2D(target, level, internalformat, x, y, width, height, border);
},
copyTexSubImage2D(target, level, xoff, yoff, x, y, width, height) {
gl.copyTexSubImage2D(target, level, xoff, yoff, x, y, width, height);
gl.readPixels(x, y, width, height, format, type, pixeldata);
},
readBuffer(src) { gl.readBuffer(src); },
- renderbufferStorageMultisample(target, samples, internalforamt, width, height) {
- gl.renderbufferStorageMultisample(target, samples, internalforamt, width, height);
+ renderbufferStorage(target, internalformat, width, height) { gl.renderbufferStorage(target, internalformat, width, height); },
+ renderbufferStorageMultisample(target, samples, internalformat, width, height) {
+ gl.renderbufferStorageMultisample(target, samples, internalformat, width, height);
},
sampleCoverage(value, invert) { gl.sampleCoverage(value, invert); },
scissor(x, y, width, height) { gl.scissor(x, y, width, height); },
stencilMaskSeparate(face, mask) { gl.stencilMaskSeparate(face, mask); },
stencilOp(fail, zfail, mask) { gl.stencilOp(fail, zfail, mask); },
stencilOpSeparate(face, fail, zfail, zpass) { gl.stencilOpSeparate(face, fail, zfail, zpass); },
- texImage2D(target, level, internalforamt, width, height, border, format, type, pixels, pixelslen) {
+ texImage2D(target, level, internalformat, width, height, border, format, type, pixels, pixelslen) {
const data = new Uint8Array(window.ONYX_MEMORY.buffer, pixels, pixelslen);
- gl.texImage2D(target, level, internalforamt, width, height, border, format, type, data);
+ gl.texImage2D(target, level, internalformat, width, height, border, format, type, data);
},
texParameterf(target, pname, param) { gl.texParameterf(target, pname, param); },
texParameteri(target, pname, param) { gl.texParameteri(target, pname, param); },
+ texStorage2D(target, levels, internalformat, width, height) { gl.texStorage2D(target, levels, internalformat, width, height); },
texSubImage2D(target, level, xoff, yoff, width, height, format, type, pixels, pixelslen) {
const data = new Uint8Array(window.ONYX_MEMORY.buffer, pixels, pixelslen);
gl.texSubImage2D(target, level, xoff, yoff, width, height, format, type, data);
package config
+#if (package runtime).Runtime != (package runtime).Runtime_Wasi {
+
+use package immediate_mode { Color4 }
+
+
+Colors : struct {
+ dark_background : Color4;
+ background : Color4;
+ foreground : Color4;
+
+ keyword : Color4;
+ value : Color4;
+ jumppoint : Color4;
+
+ primary : Color4;
+ primary_light : Color4;
+ primary_dark : Color4;
+ primary_text : Color4;
+ secondary : Color4;
+ secondary_light : Color4;
+ secondary_dark : Color4;
+ secondary_text : Color4;
+}
+
+}
start_loop();
}
+test_canvas : gfx.Canvas;
+
init :: () {
gl.init("main_canvas");
events.init();
gfx.immediate_renderer_init();
+ load_colors();
ui.init_ui();
gl.enable(gl.BLEND);
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
+
+ test_canvas = gfx.create_canvas(1000, 1000);
+ {
+ time_now :: () -> i32 #foreign "decompiler" "time_now" ---
+ random.set_seed(time_now() / 1000);
+
+ gfx.use_canvas(^test_canvas);
+ defer gfx.use_canvas(null);
+
+ gl.clearColor(0, 0, 0, 0.6);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gfx.set_mode(.Lines);
+ gfx.set_texture();
+ gl.lineWidth(10);
+
+ pv := gfx.Vector2.{ 0, 0 };
+ for i: 11 {
+ pv = .{ ~~random.between(0, 1000), ~~random.between(0, 1000) };
+ gfx.vertex(pv, config.Colors.primary);
+
+ pv = .{ ~~random.between(0, 1000), ~~random.between(0, 1000) };
+ gfx.vertex(pv, config.Colors.primary);
+ }
+
+ gfx.set_mode(.Triangles);
+ }
+
+ load_colors :: () {
+ json :: package json
+
+ @DynamicLoading // Currently, this file is just baked into the binary. When a mechanism
+ // is added to easily ask JS to make a fetch request for a file, that can be used here.
+ colors_json := #file_contents "res/colors.json";
+
+ arena := alloc.arena.make(context.allocator, 4096);
+ defer alloc.arena.free(^arena);
+ colors := json.decode(colors_json, alloc.arena.make_allocator(^arena));
+ defer json.free(colors);
+
+ config.Colors.dark_background = decode_color(colors.root["dark_background"]);
+ config.Colors.background = decode_color(colors.root["background"]);
+ config.Colors.foreground = decode_color(colors.root["foreground"]);
+
+ config.Colors.keyword = decode_color(colors.root["keyword"]);
+ config.Colors.value = decode_color(colors.root["value"]);
+ config.Colors.jumppoint = decode_color(colors.root["jumppoint"]);
+
+ config.Colors.primary = decode_color(colors.root["primary"]);
+ config.Colors.primary_light = decode_color(colors.root["primary_light"]);
+ config.Colors.primary_dark = decode_color(colors.root["primary_dark"]);
+ config.Colors.primary_text = decode_color(colors.root["primary_text"]);
+
+ config.Colors.secondary = decode_color(colors.root["secondary"]);
+ config.Colors.secondary_light = decode_color(colors.root["secondary_light"]);
+ config.Colors.secondary_dark = decode_color(colors.root["secondary_dark"]);
+ config.Colors.secondary_text = decode_color(colors.root["secondary_text"]);
+
+ decode_color :: (v: ^json.Value) -> gfx.Color4 {
+ return .{
+ r = ~~v[0]->as_float(),
+ g = ~~v[1]->as_float(),
+ b = ~~v[2]->as_float(),
+ };
+ }
+ }
}
+
last_time := 0;
#export "loop" () {
time_now :: () -> i32 #foreign "decompiler" "time_now" ---
window_height = event.resize.height;
gl.setSize(event.resize.width, event.resize.height);
- gl.viewport(0, 0, event.resize.width, event.resize.height);
- gfx.use_ortho_projection(0, ~~window_width, 0, ~~window_height);
+ gfx.set_window_size(event.resize.width, event.resize.height);
}
}
}
update :: (dt: f32) {
}
-red := 1.0f;
draw :: () {
- gl.clearColor(red, 0, 0, 1);
+ bg_color := config.Colors.background;
+ gl.clearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
gl.clear(gl.COLOR_BUFFER_BIT);
- if ui.button(.{ 100, 100, 300, 200 }, "Test") {
- red = 1 - red;
- }
+ window_rectangle := ui.Rectangle.{ 0, 0, ~~window_width, ~~window_height };
+
+ draw_background_lines(~~window_width, ~~window_height, 0, 0, line_color=config.Colors.dark_background);
+ draw_menu_bar(window_rectangle);
+
+ gfx.set_texture(^test_canvas.color_texture);
+ gfx.textured_rect(.{ 300, 100 }, .{ 800, 400 }, .{ 0, 0 }, .{ 1, 1 });
+ gfx.set_texture();
gfx.flush();
ui.clear_buttons();
}
+
+#private_file
+draw_menu_bar :: (window_rectangle: ui.Rectangle) {
+ menu_bar, _ := ui.Flow.split_horizontal(window_rectangle, top_height=32);
+
+ ui.draw_rect(menu_bar, color=.{ 0.2, 0.2, 0.2 });
+
+ menu_button_theme := ui.default_button_theme;
+ menu_button_theme.border_width = 2;
+ menu_button_theme.font_size = .9;
+
+ button_rect : ui.Rectangle;
+
+ button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+ ui.button(button_rect, "File", theme=^menu_button_theme);
+ button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+ ui.button(button_rect, "Edit", theme=^menu_button_theme);
+ button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+ ui.button(button_rect, "View", theme=^menu_button_theme);
+ button_rect, menu_bar = ui.Flow.split_vertical(menu_bar, left_width=100);
+ ui.button(button_rect, "Help", theme=^menu_button_theme);
+}
+
+#private_file
+draw_background_lines :: (width: f32, height: f32, offset_x: f32, offset_y: f32, line_color := gfx.Color4.{0.2, 0.2, 0.2}, line_spacing := 32.0f) {
+ gl :: package gl
+
+ gfx.set_mode(.Lines);
+ gfx.set_texture();
+ gl.lineWidth(4);
+
+ // "Modulus" to the nearest (-line_spacing, line_spacing) for both x and y.
+ offset_x /= line_spacing;
+ offset_y /= line_spacing;
+ offset_x = line_spacing * (offset_x - math.trunc(offset_x));
+ offset_y = line_spacing * (offset_y - math.trunc(offset_y));
+
+ for i: cast(i32) (math.ceil(width / line_spacing)) + 1 {
+ x := offset_x + ~~i * line_spacing;
+ gfx.vertex(.{ x, 0 }, line_color);
+ gfx.vertex(.{ x, height }, line_color);
+ }
+
+ for i: cast(i32) (math.ceil(height / line_spacing)) + 1 {
+ y := offset_y + ~~i * line_spacing;
+ gfx.vertex(.{ 0, y }, line_color);
+ gfx.vertex(.{ width, y }, line_color);
+ }
+
+ gfx.set_mode(.Triangles);
+}