Skip to content

Commit

Permalink
Add a bezier curve example and make 2 canvases for 2d and webgl
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed May 10, 2024
1 parent 81562c7 commit 771f685
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 75 deletions.
50 changes: 48 additions & 2 deletions example/bezier_curve.odin
Original file line number Diff line number Diff line change
@@ -1,16 +1,62 @@
//+private file
package example

import gl "../wasm/webgl"
import "core:fmt"

import gl "../wasm/webgl"
import ctx "../wasm/ctx2d"

ratio :: distinct f32
rvec2 :: distinct [2]f32

to_px :: proc(r: rvec2) -> vec2 {
return vec2(r) * vec2(canvas_size) * dpr
}

@private
State_Bezier_Curve :: struct {
points: [4]rvec2,
t: f32,
}

@private
setup_bezier_curve :: proc(s: ^State_Bezier_Curve, program: gl.Program) {
setup_bezier_curve :: proc(s: ^State_Bezier_Curve, _: gl.Program) {
ok := ctx.setCurrentContextById("canvas-0")
if !ok {
fmt.eprintfln("failed to set current context")
return
}

s.points[0] = {0.3, 0.7}
s.points[1] = {0.3, 0.3}
s.points[2] = {0.7, 0.3}
s.points[3] = {0.7, 0.7}
}

@private
frame_bezier_curve :: proc(s: ^State_Bezier_Curve, delta: f32) {

px_points: [4]vec2
for p, i in s.points {
px_points[i] = to_px(p)
}

ctx.clearRect(0, 0, canvas_size.x, canvas_size.y)

ctx.strokeStyle(GRAY)
for p, i in px_points[1:] {
ctx.beginPath()
ctx.moveTo(p)
ctx.lineTo(px_points[i])
ctx.stroke()
}

ctx.fillStyle (GRAY)
ctx.strokeStyle(WHITE)
for p in px_points {
ctx.beginPath()
ctx.arc(p, 6, 0, 2 * PI)
ctx.fill()
ctx.stroke()
}
}
4 changes: 2 additions & 2 deletions example/boxes.odin
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package example
import glm "core:math/linalg/glsl"
import gl "../wasm/webgl"

CUBE_COLORS: [CUBE_VERTICES]RGBA : {
CUBE_COLORS: [CUBE_VERTICES]rgba : {
GREEN, GREEN, GREEN, // 0
GREEN, GREEN, GREEN, // 1
YELLOW, YELLOW, YELLOW, // 2
Expand Down Expand Up @@ -42,7 +42,7 @@ setup_boxes :: proc(s: ^State_Boxes, program: gl.Program) {
gl.Enable(gl.DEPTH_TEST) // draw only closest faces

positions: [BOXES_AMOUNT * CUBE_VERTICES]vec3
colors : [BOXES_AMOUNT * CUBE_VERTICES]RGBA
colors : [BOXES_AMOUNT * CUBE_VERTICES]rgba

for i in 0..<BOXES_AMOUNT {
cube_positions := get_cube_positions(
Expand Down
4 changes: 2 additions & 2 deletions example/camera.odin
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import gl "../wasm/webgl"
ALL_PYRAMID_VERTICES :: AMOUNT * PYRAMID_VERTICES
ALL_VERTICES :: ALL_PYRAMID_VERTICES + CUBE_VERTICES

PYRAMID_COLORS: [PYRAMID_VERTICES]RGBA : {
PYRAMID_COLORS: [PYRAMID_VERTICES]rgba : {
BLUE, BLUE, BLUE, // 0
BLUE, BLUE, BLUE, // 1
YELLOW, YELLOW, YELLOW, // 2
Expand Down Expand Up @@ -40,7 +40,7 @@ setup_camera :: proc(s: ^State_Camera, program: gl.Program) {
gl.Enable(gl.DEPTH_TEST) // draw only closest faces

positions: [ALL_VERTICES]vec3
colors : [ALL_VERTICES]RGBA
colors : [ALL_VERTICES]rgba

/* Pyramids */
for i in 0..<AMOUNT {
Expand Down
2 changes: 1 addition & 1 deletion example/lighting.odin
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ State_Lighting :: struct {
ring_angle: f32,
positions : [ALL_VERTICES]vec3,
normals : [ALL_VERTICES]vec3,
colors : [ALL_VERTICES]RGBA,
colors : [ALL_VERTICES]rgba,
}

@private
Expand Down
4 changes: 3 additions & 1 deletion example/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
<link rel="stylesheet" href="styles.css" />
</head>
<body id="body">
<canvas id="canvas" width="640" height="480"></canvas>
<canvas id="canvas-0" width="640" height="480"></canvas>
<canvas id="canvas-1" width="640" height="480"></canvas>
<div id="canvas-bg"></div>

<a class="github-link" href="https://github.com/thetarnav/odin-wasm" target="_blank">
<img
Expand Down
5 changes: 4 additions & 1 deletion example/public/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,14 @@ code {
right: 0;
}

#canvas {
canvas, #canvas-bg {
position: absolute;
top: 10%;
left: 10%;
width: 80%;
height: 80%;
}

#canvas-bg {
background-color: rgba(30, 40, 50, 0.1);
}
2 changes: 1 addition & 1 deletion example/pyramid.odin
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ positions: [VERTICES]vec3 = {
{ 0, 0, -SIDE/2},
{ 0, 0, SIDE/2},
}
colors: [VERTICES]RGBA = {
colors: [VERTICES]rgba = {
GREEN, YELLOW, BLUE,
RED, BLUE, YELLOW,
GREEN, RED, YELLOW,
Expand Down
64 changes: 37 additions & 27 deletions example/setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,32 @@ Example selection

/** @enum {(typeof Example_Kind)[keyof typeof Example_Kind]} */
const Example_Kind = /** @type {const} */ ({
Rectangle : 0,
Pyramid : 1,
Boxes : 2,
Camera : 3,
Lighting : 4,
Specular : 5,
Spotlight : 6,
Candy : 7,
Sol_System: 8,
Rectangle : 0,
Pyramid : 1,
Boxes : 2,
Camera : 3,
Lighting : 4,
Specular : 5,
Spotlight : 6,
Candy : 7,
Sol_System : 8,
Bezier_Curve: 9,
})
/** @type {Example_Kind[]} */
const example_kinds = Object.values(Example_Kind)

/** @type {Record<Example_Kind, string>} */
const example_kind_href_hashes = {
[Example_Kind.Rectangle] : "#rectangle",
[Example_Kind.Pyramid] : "#pyramid",
[Example_Kind.Boxes] : "#boxes",
[Example_Kind.Camera] : "#camera",
[Example_Kind.Lighting] : "#lighting",
[Example_Kind.Specular] : "#specular",
[Example_Kind.Spotlight] : "#spotlight",
[Example_Kind.Candy] : "#candy",
[Example_Kind.Sol_System]: "#sol-system",
[Example_Kind.Rectangle] : "#rectangle",
[Example_Kind.Pyramid] : "#pyramid",
[Example_Kind.Boxes] : "#boxes",
[Example_Kind.Camera] : "#camera",
[Example_Kind.Lighting] : "#lighting",
[Example_Kind.Specular] : "#specular",
[Example_Kind.Spotlight] : "#spotlight",
[Example_Kind.Candy] : "#candy",
[Example_Kind.Sol_System] : "#sol-system",
[Example_Kind.Bezier_Curve]: "#bezier-curve",
}

/** @type {Example_Kind} */
Expand Down Expand Up @@ -114,15 +116,17 @@ Wasm instance
* @returns {void }
*/

const wasm_state = wasm.makeWasmState()
const wasm_state = wasm.makeWasmState()
const webgl_state = wasm.webgl.makeWebGLState()
const ctx2d_state = new wasm.ctx2d.Ctx2d_State()

const src_instance = await wasm.fetchInstanciateWasm(WASM_FILENAME, {
env: {}, // TODO
odin_env: wasm.env.makeOdinEnv(wasm_state),
odin_dom: wasm.dom.makeOdinDOM(wasm_state),
webgl : wasm.webgl.makeOdinWebGL(wasm_state, webgl_state),
webgl2 : wasm.webgl.makeOdinWegGL2(wasm_state, webgl_state),
odin_env: wasm.env .makeOdinEnv (wasm_state),
odin_dom: wasm.dom .makeOdinDOM (wasm_state),
webgl : wasm.webgl.makeOdinWebGL (wasm_state, webgl_state),
webgl2 : wasm.webgl.makeOdinWegGL2 (wasm_state, webgl_state),
ctx2d : wasm.ctx2d.make_odin_ctx2d(wasm_state, ctx2d_state),
})

wasm.initWasmState(wasm_state, src_instance)
Expand Down Expand Up @@ -157,13 +161,19 @@ void requestAnimationFrame(prev_time => {
void requestAnimationFrame(frame)
})

const canvas = /** @type {HTMLCanvasElement} */ (document.getElementById("canvas"))
/* One canvas for webgl and the other for 2d */
const canvas_0 = /** @type {HTMLCanvasElement} */ (document.getElementById("canvas-1"))
const canvas_1 = /** @type {HTMLCanvasElement} */ (document.getElementById("canvas-0"))
const dpr = window.devicePixelRatio || 1

function updateCanvasSize() {
const rect = canvas.getBoundingClientRect()
canvas.width = rect.width * dpr
canvas.height = rect.height * dpr
const rect = canvas_0.getBoundingClientRect()

canvas_0.width = rect.width * dpr
canvas_0.height = rect.height * dpr
canvas_1.width = rect.width * dpr
canvas_1.height = rect.height * dpr

exports.on_window_resize(
window.innerWidth,
window.innerHeight,
Expand Down
43 changes: 26 additions & 17 deletions example/setup.odin
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "core:mem"
import "core:runtime"
import "core:math/rand"

import "../wasm/dom"
import "../wasm/dom"
import gl "../wasm/webgl"

canvas_res: [2]i32
Expand All @@ -20,16 +20,16 @@ aspect_ratio: f32
scale: f32 = 0.5

Example_Kind :: enum {
Rectangle,
Pyramid,
Boxes,
Camera,
Lighting,
Specular,
Spotlight,
Candy,
Sol_System,
Bezier_Curve,
Rectangle = 0,
Pyramid = 1,
Boxes = 2,
Camera = 3,
Lighting = 4,
Specular = 5,
Spotlight = 6,
Candy = 7,
Sol_System = 8,
Bezier_Curve = 9,
}
example: Example_Kind

Expand Down Expand Up @@ -142,23 +142,32 @@ on_window_resize :: proc "c" (vw, vh, cw, ch, cx, cy: f32) {

@export
start :: proc "c" (ctx: ^runtime.Context, example_kind: Example_Kind) -> (ok: bool) {
example = example_kind
demo := demos[example]

context = ctx^
context.allocator = forever_arena_allocator
context.temp_allocator = temp_arena_allocator
defer free_all(context.temp_allocator)

example = example_kind
program: gl.Program

// Make sure that this matches the id of your canvas.
if ok = gl.SetCurrentContextById("canvas"); !ok {
if ok = gl.SetCurrentContextById("canvas-1"); !ok {
fmt.eprintln("Failed to set current context!")
return false
}

// Some examples don't use webgl shaders
if len(demo.vs_sources) == 0 {
demo.vs_sources = {"void main() {}"}
}
if len(demo.fs_sources) == 0 {
demo.fs_sources = {"void main() {}"}
}

demo := demos[example]

program, program_ok := gl.CreateProgramFromStrings(demo.vs_sources, demo.fs_sources)
if !program_ok {
program, ok = gl.CreateProgramFromStrings(demo.vs_sources, demo.fs_sources)
if !ok {
fmt.eprintln("Failed to create program!")
return false
}
Expand Down
22 changes: 11 additions & 11 deletions example/shapes.odin
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package example


WHITE :: RGBA{255, 255, 255, 255}
GREEN :: RGBA{ 60, 210, 0, 255}
YELLOW :: RGBA{210, 200, 0, 255}
BLUE :: RGBA{ 0, 80, 190, 255}
CYAN :: RGBA{ 0, 210, 210, 255}
RED :: RGBA{230, 20, 0, 255}
ORANGE :: RGBA{250, 150, 50, 255}
PURPLE :: RGBA{160, 100, 200, 255}
PURPLE_DARK :: RGBA{ 80, 30, 30, 255}
BLACK :: RGBA{ 0, 0, 0, 255}
GRAY :: RGBA{ 80, 80, 80, 255}
WHITE :: rgba{255, 255, 255, 255}
GREEN :: rgba{ 60, 210, 0, 255}
YELLOW :: rgba{210, 200, 0, 255}
BLUE :: rgba{ 0, 80, 190, 255}
CYAN :: rgba{ 0, 210, 210, 255}
RED :: rgba{230, 20, 0, 255}
ORANGE :: rgba{250, 150, 50, 255}
PURPLE :: rgba{160, 100, 200, 255}
PURPLE_DARK :: rgba{ 80, 30, 30, 255}
BLACK :: rgba{ 0, 0, 0, 255}
GRAY :: rgba{ 80, 80, 80, 255}


CUBE_TRIANGLES :: 6 * 2
Expand Down
4 changes: 2 additions & 2 deletions example/specular.odin
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ State_Specular :: struct {
ball_angle: f32,
positions : [ALL_VERTICES]vec3,
normals : [ALL_VERTICES]vec3,
colors : [ALL_VERTICES]RGBA,
colors : [ALL_VERTICES]rgba,
}

@private
Expand All @@ -48,7 +48,7 @@ setup_specular :: proc(s: ^State_Specular, program: gl.Program) {
ball_colors := s.colors [CUBE_VERTICES:]

get_sphere_base_triangle(ball_positions, ball_normals, BALL_RADIUS, BALL_SEGMENTS)
copy_pattern(ball_colors, []RGBA{PURPLE, CYAN, CYAN, PURPLE, CYAN, PURPLE})
copy_pattern(ball_colors, []rgba{PURPLE, CYAN, CYAN, PURPLE, CYAN, PURPLE})

attribute(s.a_position, gl.CreateBuffer(), s.positions[:])
attribute(s.a_normal , gl.CreateBuffer(), s.normals[:])
Expand Down
7 changes: 4 additions & 3 deletions example/utils.odin
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ bvec4 :: distinct [4]b32
mat2 :: glm.mat2
mat3 :: glm.mat3
mat4 :: glm.mat4
u8vec4 :: distinct [4]u8
RGBA :: u8vec4
u8vec4 :: [4]u8
rgba :: u8vec4

PI :: glm.PI
VAO :: gl.VertexArrayObject
Expand Down Expand Up @@ -378,7 +378,8 @@ copy_pattern :: #force_inline proc "contextless" (dst: []$S, src: []S) #no_bound
}

cast_vec2 :: #force_inline proc "contextless" ($D: typeid, v: [2]$S) -> [2]D
where intrinsics.type_is_numeric(S) && intrinsics.type_is_numeric(D) {
where intrinsics.type_is_numeric(S),
intrinsics.type_is_numeric(D) {
return {D(v.x), D(v.y)}
}

Expand Down
2 changes: 2 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const ODIN_ARGS_SHARED = [
]
/** @type {string[]} */
const ODIN_ARGS_DEV = [
"-o:none",
"-use-separate-modules",
]
/** @type {string[]} */
const ODIN_ARGS_RELESE = [
Expand Down
Loading

0 comments on commit 771f685

Please sign in to comment.