Skip to content

Commit

Permalink
Parse and display chair with materials
Browse files Browse the repository at this point in the history
  • Loading branch information
thetarnav committed Jan 11, 2025
1 parent 560065d commit c5ea30d
Show file tree
Hide file tree
Showing 15 changed files with 425 additions and 117 deletions.
30 changes: 13 additions & 17 deletions example/book.odin
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
package example

import glm "core:math/linalg/glsl"
import "core:slice"
import gl "../wasm/webgl"
import "../obj"

@private
State_Book :: struct {
using locations: Input_Locations_Boxes,
vao: VAO,
positions: []vec3,
colors: []u8vec4,
vertices: Vertices,
rotation: mat4,
}

Expand All @@ -21,26 +19,24 @@ setup_book :: proc(s: ^State_Book, program: gl.Program) {
gl.Enable(gl.CULL_FACE) // don't draw back faces
gl.Enable(gl.DEPTH_TEST) // draw only closest faces

objects := obj.parse_file(#load("./public/book.obj", string), context.temp_allocator)

obj_data := obj.parse_file(#load("./public/book.obj", string), context.temp_allocator)
s.vao = gl.CreateVertexArray()

o := &obj_data.objects[0]


object := &objects[0]
s.positions = slice.clone(object.vertices.position[:len(object.vertices)])

extent_min, extent_max := get_extents(s.positions)
correct_extents(s.positions, extent_min, extent_max, -140, 140)
s.vertices = convert_obj_vertices(o.vertices[:])

s.colors = vec3_slice_to_rgba(object.vertices.color[:len(object.vertices)])
extent_min, extent_max := get_extents(obj_data.positions[:])
correct_extents(s.vertices.position[:len(s.vertices)], extent_min, extent_max, -140, 140)


gl.BindVertexArray(s.vao)

input_locations_boxes(&s.locations, program)

attribute(s.a_position, gl.CreateBuffer(), s.positions)
attribute(s.a_color , gl.CreateBuffer(), s.colors)
attribute(s.a_position, gl.CreateBuffer(), s.vertices.position[:len(s.vertices)])
attribute(s.a_color, gl.CreateBuffer(), s.vertices.color[:len(s.vertices)])

/* Init rotation */
s.rotation = 1
Expand All @@ -59,16 +55,16 @@ frame_book :: proc(s: ^State_Book, delta: f32) {

mat: mat4 = 1
mat *= glm.mat4PerspectiveInfinite(
fovy = glm.radians_f32(80),
fovy = radians(80),
aspect = aspect_ratio,
near = 1,
)
mat *= glm.mat4Translate({0, 0, -900 + scale * 720})
mat *= mat4_translate({0, 0, -900 + scale * 720})
mat *= s.rotation

gl.BindVertexArray(s.vao)

uniform(s.u_matrix, mat)

gl.DrawArrays(gl.TRIANGLES, 0, len(s.positions))
gl.DrawArrays(gl.TRIANGLES, 0, len(s.vertices))
}
6 changes: 3 additions & 3 deletions example/boxes.odin
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,13 @@ frame_boxes :: proc(s: ^State_Boxes, delta: f32) {
rotation := -0.01 * delta * mouse_rel.yx
s.rotation = mat4_rotate_x(rotation.x) * mat4_rotate_y(rotation.y) * s.rotation

mat: mat4 = 1
mat := mat4(1)
mat *= glm.mat4PerspectiveInfinite(
fovy = glm.radians_f32(80),
fovy = radians(80),
aspect = aspect_ratio,
near = 1,
)
mat *= glm.mat4Translate({0, 0, -900 + scale * 720})
mat *= mat4_translate({0, 0, -900 + scale * 720})
mat *= s.rotation

uniform(s.u_matrix, mat)
Expand Down
4 changes: 2 additions & 2 deletions example/candy.odin
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,11 @@ frame_candy :: proc(s: ^State_Candy, delta: f32) {

view_mat: mat4 = 1
view_mat *= glm.mat4PerspectiveInfinite(
fovy = glm.radians_f32(80),
fovy = radians(80),
aspect = aspect_ratio,
near = 1,
)
view_mat *= glm.mat4Translate({0, 0, -900 + scale * 720})
view_mat *= mat4_translate({0, 0, -900 + scale * 720})
view_mat *= s.rotation


Expand Down
40 changes: 40 additions & 0 deletions example/chair.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#version 300 es

precision highp float;

in vec3 v_normal;
in vec4 v_color;
in vec3 v_surface_to_eye;

uniform vec3 u_diffuse;
uniform vec3 u_ambient;
uniform vec3 u_emissive;
uniform vec3 u_specular;
uniform float u_shininess;
uniform float u_opacity;
uniform vec3 u_light_dir;
uniform vec3 u_light_ambient;

out vec4 out_color;

void main() {
// varying variables are interpolated
vec3 normal = normalize(v_normal);
vec3 surface_to_eye = normalize(v_surface_to_eye);
vec3 half_vector = normalize(surface_to_eye + u_light_dir);

float light_fake = dot(u_light_dir, normal) * .5 + .5;
float light_specular = clamp(dot(normal, half_vector), 0.0, 1.0);

vec3 effective_diffuse = u_diffuse * v_color.rgb;
float effective_opacity = u_opacity * v_color.a;

out_color = vec4(
(
u_emissive +
u_ambient * u_light_ambient +
effective_diffuse * light_fake +
u_specular * pow(light_specular, u_shininess)
),
effective_opacity);
}
90 changes: 59 additions & 31 deletions example/chair.odin
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package example

import glm "core:math/linalg/glsl"
import "core:slice"
import gl "../wasm/webgl"
import "../obj"

Expand All @@ -13,46 +12,59 @@ State_Chair :: struct {
}

Shape :: struct {
using locations: Input_Locations_Boxes,
vao : VAO,
positions: []vec3,
colors : []u8vec4,
using uniforms: Uniform_Values_Chair,
locations: Input_Locations_Chair,
vao: VAO,
vertices: Vertices,
material: obj.Material,
}

chair_obj_bytes := #load("./public/chair.obj", string)
chair_obj_src := #load("./public/chair.obj", string)
chair_mtl_src := #load("./public/chair.mtl", string)

@private
setup_chair :: proc(s: ^State_Chair, program: gl.Program) {

gl.Enable(gl.CULL_FACE) // don't draw back faces
gl.Enable(gl.DEPTH_TEST) // draw only closest faces

objects := obj.parse_file(#load("./public/chair.obj", string), context.temp_allocator)
obj_data, obj_parse_err := obj.parse_file(chair_obj_src, context.temp_allocator)
if obj_parse_err != nil {
fmt.eprintf("Obj parse error: %v", obj_parse_err)
}

extent_min, extent_max := get_extents(objects[0].vertices.position[:len(objects[0].vertices)])
for o in objects[1:] {
extend_extents(&extent_min, &extent_max, o.vertices.position[:len(o.vertices)])
materials, mtl_parse_err := obj.parse_mtl_file(chair_mtl_src)
if obj_parse_err != nil {
fmt.eprintf("Mtl parse error: %v", mtl_parse_err)
}

s.shapes = make([]Shape, len(objects))
extent_min, extent_max := get_extents(obj_data.positions[:])

s.shapes = make([]Shape, len(obj_data.objects))

for &shape, i in s.shapes {
o := objects[i]
o := obj_data.objects[i]

shape.vao = gl.CreateVertexArray()

shape.positions = slice.clone(o.vertices.position[:len(o.vertices)])
correct_extents(shape.positions, extent_min, extent_max, -200, 200)

shape.colors = make([]rgba, len(shape.positions))
slice.fill(shape.colors, rand_color())

shape.vertices = convert_obj_vertices(o.vertices[:])

correct_extents(shape.vertices.position[:len(shape.vertices)], extent_min, extent_max, -200, 200)

for m in materials {
if m.name == o.material {
shape.material = m
break
}
}

gl.BindVertexArray(shape.vao)

input_locations_boxes(&shape.locations, program)
input_locations_chair(&shape.locations, program)

attribute(shape.a_position, gl.CreateBuffer(), shape.positions)
attribute(shape.a_color, gl.CreateBuffer(), shape.colors)
attribute(shape.locations.a_position, gl.CreateBuffer(), shape.vertices.position[:len(shape.vertices)])
attribute(shape.locations.a_color, gl.CreateBuffer(), shape.vertices.color[:len(shape.vertices)])
attribute(shape.locations.a_normal, gl.CreateBuffer(), shape.vertices.normal[:len(shape.vertices)])
}

/* Init rotation */
Expand All @@ -70,24 +82,40 @@ frame_chair :: proc(s: ^State_Chair, delta: f32) {
rotation := -0.01 * delta * mouse_rel.yx
s.rotation = mat4_rotate_x(rotation.x) * mat4_rotate_y(rotation.y) * s.rotation

mat: mat4 = 1
mat *= glm.mat4PerspectiveInfinite(
fovy = glm.radians_f32(80),
eye_pos := vec3{0, 0, 500 - 500 * (scale-0.5)}

eye_mat := mat4(1)
eye_mat *= mat4_translate(eye_pos)
eye_mat = glm.inverse_mat4(eye_mat)

view_mat := glm.mat4PerspectiveInfinite(
fovy = radians(80),
aspect = aspect_ratio,
near = 1,
)
mat *= glm.mat4Translate({0, 0, -900 + scale * 720})
mat *= s.rotation
view_mat *= eye_mat

local_mat: mat4 = 1
local_mat *= s.rotation

for &shape in s.shapes {

for &o in s.shapes {
shape.u_local = local_mat
shape.u_view = view_mat
shape.u_eye_position = eye_pos
shape.u_light_dir = normalize(vec3{-1, 3, 5})

gl.BindVertexArray(o.vao)
shape.u_diffuse = shape.material.diffuse
shape.u_ambient = shape.material.ambient
shape.u_emissive = shape.material.emissive
shape.u_specular = shape.material.specular
shape.u_shininess = shape.material.shininess
shape.u_opacity = shape.material.opacity

uniform(o.u_matrix, mat)
gl.BindVertexArray(shape.vao)

uniforms_chair(shape.locations, shape)

gl.DrawArrays(gl.TRIANGLES, 0, len(o.positions))
gl.DrawArrays(gl.TRIANGLES, 0, len(shape.vertices))
}

}
31 changes: 31 additions & 0 deletions example/chair.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#version 300 es

in vec3 a_position;
in vec3 a_normal;
in vec4 a_color;

uniform mat4 u_view;
uniform mat4 u_local;
uniform vec3 u_eye_position;

out vec3 v_normal;
out vec4 v_color;
out vec3 v_surface_to_eye;

void main() {
vec4 local_pos = u_local * vec4(a_position, 1.0);

// project the position
gl_Position = u_view * local_pos;

/*
orient the normals
mat3() is the upper 3x3 - orientation, no translation
*/
v_normal = mat3(u_local) * a_normal;

v_surface_to_eye = u_eye_position - local_pos.xyz;

v_color = a_color;
}
2 changes: 1 addition & 1 deletion example/public/book.obj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Book model by Oleaf
# License: CC-BY-NC
# https://sketchfab.com/3d-models/book-vertex-chameleon-study-51b0b3bdcd844a9e951a9ede6f192da8
mtllib ./book.obj.mtl
mtllib book.mtl

vn -0.000000 0.002373 -0.000000
vt 0.000000 0.316049
Expand Down
Loading

0 comments on commit c5ea30d

Please sign in to comment.