main.odin ¶
1
2
3
4
5package webgl_triangle
6
7import "core:sys/wasm/js"
8import gl "vendor:wasm/WebGL"
9
10
11CANVAS_ID :: "webgl-canvas"
12
13shader: gl.Program
14vertex_buffer: gl.Buffer
15
16
17main :: proc() {
18 js.add_window_event_listener(.Resize, nil, resize_callback)
19 gl.CreateCurrentContextById(CANVAS_ID, gl.DEFAULT_CONTEXT_ATTRIBUTES)
20 gl.SetCurrentContextById(CANVAS_ID)
21 shader = gl.CreateProgramFromStrings({SHADER_VERT}, {SHADER_FRAG}) or_else panic("Failed loading shader")
22
23 vertex_buffer = gl.CreateBuffer()
24 gl.BindBuffer(gl.ARRAY_BUFFER, vertex_buffer)
25 gl.BufferData(gl.ARRAY_BUFFER, size_of(triangle_vertices), raw_data(&triangle_vertices), gl.DYNAMIC_DRAW)
26
27
28 attr_pos := gl.GetAttribLocation(shader, "in_position")
29 gl.EnableVertexAttribArray(attr_pos)
30 gl.VertexAttribPointer(attr_pos, 3, gl.FLOAT, false, size_of(Vertex), offset_of(Vertex, pos))
31
32 attr_col := gl.GetAttribLocation(shader, "in_color")
33 gl.EnableVertexAttribArray(attr_col)
34 gl.VertexAttribPointer(attr_col, 4, gl.UNSIGNED_BYTE, true, size_of(Vertex), offset_of(Vertex, color))
35
36 update_canvas_size()
37 gl.Disable(gl.DEPTH_TEST)
38 gl.Enable(gl.BLEND)
39 gl.Enable(gl.CULL_FACE)
40 gl.CullFace(gl.BACK)
41 gl.FrontFace(gl.CW)
42 gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
43}
44
45
46@(export)
47step :: proc(dt: f32) -> bool {
48 gl.ClearColor(0, 0, 0, 1)
49 gl.Clear(u32(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT))
50 gl.UseProgram(shader)
51 gl.DrawArrays(gl.TRIANGLES, 0, len(triangle_vertices))
52 return true
53}
54
55Vertex :: struct {
56 pos: [3]f32,
57 color: [4]u8,
58}
59
60triangle_vertices := [3]Vertex {
61 {
62 pos = { 0.0, 0.5, 0.0 },
63 color = {255, 0, 0, 255},
64 },
65 {
66 pos = { 0.5, -0.5, 0.0 },
67 color = { 0, 255, 0, 255 },
68 },
69 {
70 pos = { -0.5, -0.5, 0.0 },
71 color = { 0, 0, 255, 255 },
72 },
73}
74
75update_canvas_size :: proc() {
76 rect := js.get_bounding_client_rect(CANVAS_ID)
77 dpi := js.device_pixel_ratio()
78
79 width := f64(rect.width) * dpi
80 height := f64(rect.height) * dpi
81
82 js.set_element_key_f64(CANVAS_ID, "width", width)
83 js.set_element_key_f64(CANVAS_ID, "height", height)
84 gl.Viewport(0, 0, i32(width), i32(height))
85}
86
87resize_callback :: proc(e: js.Event) {
88 update_canvas_size()
89}
90
91SHADER_VERT :: `
92precision highp float;
93
94attribute vec3 in_position;
95attribute vec4 in_color;
96
97varying vec4 color;
98
99void main() {
100 color = in_color;
101 gl_Position = vec4(in_position, 1.0);
102}
103`
104
105SHADER_FRAG :: `
106precision highp float;
107
108varying vec4 color;
109
110void main() {
111 gl_FragColor = color;
112}
113`