diff --git a/constants.odin b/constants.odin index a46e4a7..cb29ff0 100644 --- a/constants.odin +++ b/constants.odin @@ -6,7 +6,7 @@ GL_VERSION_MINOR :: 1 WINDOW_WIDTH :: 800 WINDOW_HEIGHT :: 600 -SHADERS_EXTENSION :: ".glsl" +SHADERS_EXTENSION :: "glsl" SHADERS_BASE_PATH :: "shaders" SHADERS_VERTEX_SEPARATOR :: "#type vertex" SHADERS_FRAGMENT_SEPARATOR :: "#type fragment" diff --git a/main.odin b/main.odin index b307d94..a06966d 100644 --- a/main.odin +++ b/main.odin @@ -1,5 +1,5 @@ -// 5. Transformations -// https://learnopengl.com/Getting-started/Transformations +// 6. Coordinate Systems +// https://learnopengl.com/Getting-started/Coordinate-Systems package main @@ -13,32 +13,76 @@ import "vendor:glfw" import stbi "vendor:stb/image" window: glfw.WindowHandle - -rect_verts := [?]f32{ - // xyz // texture coords - 0.5, 0.5, 0.0, 2.0, 2.0, // TR - 0.5, -0.5, 0.0, 2.0, 0.0, // BR - -0.5, -0.5, 0.0, 0.0, 0.0, // BL - -0.5, 0.5, 0.0, 0.0, 2.0, // TL +viewport: [4]i32 + +cube_verts := [?]f32 { + -0.5, -0.5, -0.5, 0.0, 0.0, + 0.5, -0.5, -0.5, 1.0, 0.0, + 0.5, 0.5, -0.5, 1.0, 1.0, + 0.5, 0.5, -0.5, 1.0, 1.0, + -0.5, 0.5, -0.5, 0.0, 1.0, + -0.5, -0.5, -0.5, 0.0, 0.0, + + -0.5, -0.5, 0.5, 0.0, 0.0, + 0.5, -0.5, 0.5, 1.0, 0.0, + 0.5, 0.5, 0.5, 1.0, 1.0, + 0.5, 0.5, 0.5, 1.0, 1.0, + -0.5, 0.5, 0.5, 0.0, 1.0, + -0.5, -0.5, 0.5, 0.0, 0.0, + + -0.5, 0.5, 0.5, 1.0, 0.0, + -0.5, 0.5, -0.5, 1.0, 1.0, + -0.5, -0.5, -0.5, 0.0, 1.0, + -0.5, -0.5, -0.5, 0.0, 1.0, + -0.5, -0.5, 0.5, 0.0, 0.0, + -0.5, 0.5, 0.5, 1.0, 0.0, + + 0.5, 0.5, 0.5, 1.0, 0.0, + 0.5, 0.5, -0.5, 1.0, 1.0, + 0.5, -0.5, -0.5, 0.0, 1.0, + 0.5, -0.5, -0.5, 0.0, 1.0, + 0.5, -0.5, 0.5, 0.0, 0.0, + 0.5, 0.5, 0.5, 1.0, 0.0, + + -0.5, -0.5, -0.5, 0.0, 1.0, + 0.5, -0.5, -0.5, 1.0, 1.0, + 0.5, -0.5, 0.5, 1.0, 0.0, + 0.5, -0.5, 0.5, 1.0, 0.0, + -0.5, -0.5, 0.5, 0.0, 0.0, + -0.5, -0.5, -0.5, 0.0, 1.0, + + -0.5, 0.5, -0.5, 0.0, 1.0, + 0.5, 0.5, -0.5, 1.0, 1.0, + 0.5, 0.5, 0.5, 1.0, 0.0, + 0.5, 0.5, 0.5, 1.0, 0.0, + -0.5, 0.5, 0.5, 0.0, 0.0, + -0.5, 0.5, -0.5, 0.0, 1.0, +} +cube_positions := [?]v3{ + {0, 0, 0}, + {2, 5, -15}, + {-1.5, -2.2, -2.5}, + {-3.8, -2, -12.3}, + { 2.4, -0.4, -3.5}, + {-1.7, 3, -7.5}, + {1.3, -2, -2.5}, + {1.5, 2, -2.5}, + {1.5, 0.2, -1.5}, + {-1.3, 1, -1.5}, } -rect_texture_coords := [?]f32{1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0} grass_texture, face_texture: u32 -indices := [?]u32{ // Zero-indexed - 0, 1, 3, // First triangle - 1, 2, 3 // Second triangle -} tri_verts := [?]f32{ // xyz // rgb 0.5, 0.5, 0.0, 1.0, 0.0, 0.0, 0.75, -0.5, 0.0, 0.0, 1.0, 0.0, - 0.25, -0.5, 0.0, 0.0, 0.0, 1.0 + 0.25, -0.5, 0.0, 0.0, 0.0, 1.0, } HOW_MANY :: 2 VAOs := make([]u32, HOW_MANY) VBOs := make([]u32, HOW_MANY) -EBO, rect_shader, tri_shader: u32 +cube_shader, tri_shader: u32 wireframe: bool @@ -58,6 +102,8 @@ main :: proc() { glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, gl.TRUE) } + viewport[2] = WINDOW_WIDTH + viewport[3] = WINDOW_HEIGHT window = glfw.CreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Hi mom!", nil, nil) if window == nil { fmt.print("Failed to create GLFW window\n") @@ -73,15 +119,14 @@ main :: proc() { gl.load_up_to(GL_VERSION_MAJOR, GL_VERSION_MINOR, glfw.gl_set_proc_address) fmt.println(gl.GetString(gl.VERSION)) + gl.Enable(gl.DEPTH_TEST) + gl.GenVertexArrays(HOW_MANY, raw_data(VAOs)) gl.GenBuffers(HOW_MANY, raw_data(VBOs)) - gl.GenBuffers(1, &EBO) gl.BindVertexArray(VAOs[0]) gl.BindBuffer(gl.ARRAY_BUFFER, VBOs[0]) - gl.BufferData(gl.ARRAY_BUFFER, size_of(rect_verts), &rect_verts, gl.STATIC_DRAW) - gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, EBO) - gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, size_of(indices), &indices, gl.STATIC_DRAW) + gl.BufferData(gl.ARRAY_BUFFER, size_of(cube_verts), &cube_verts, gl.STATIC_DRAW) gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 5 * size_of(f32), 0) gl.EnableVertexAttribArray(0) gl.VertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 5 * size_of(f32), 3 * size_of(f32)) @@ -95,7 +140,7 @@ main :: proc() { gl.VertexAttribPointer(1, 3, gl.FLOAT, gl.FALSE, 6 * size_of(f32), 3 * size_of(f32)) gl.EnableVertexAttribArray(1) - rect_shader, _ = load_shader("rect") + cube_shader, _ = load_shader("cube") tri_shader, _ = load_shader("triangle") stbi.set_flip_vertically_on_load(1) @@ -124,9 +169,9 @@ main :: proc() { gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, i32(image2_width), i32(image2_height), 0, gl.RGBA, gl.UNSIGNED_BYTE, image2_bytes) gl.GenerateMipmap(gl.TEXTURE_2D) - use_shader(rect_shader) - set_uniform(rect_shader, "myTexture", 0) - set_uniform(rect_shader, "myTexture2", 1) + use_shader(cube_shader) + set_uniform(cube_shader, "myTexture", 0) + set_uniform(cube_shader, "myTexture2", 1) for !glfw.WindowShouldClose(window) { render() @@ -135,11 +180,10 @@ main :: proc() { } render :: proc() { - using math time := glfw.GetTime() gl.ClearColor(0.2, 0.3, 0.3, 1.0) - gl.Clear(gl.COLOR_BUFFER_BIT) + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) if wireframe { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) @@ -147,30 +191,33 @@ render :: proc() { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } - use_shader(rect_shader) - sin_time01 := sin(time) * 0.5 + 0.5 - set_uniform(rect_shader, "myColor", v4{0.5, f32(sin_time01), 0.25, 1.0}) - set_uniform(rect_shader, "alpha", texture_alpha) - transform := mat4(1) - transform *= lalg.matrix4_translate_f32({-0.5, 0, 0}) - transform *= lalg.matrix4_rotate_f32(f32(time), {0, 0, 1}) - transform *= lalg.matrix4_scale_f32(v3(1.5)) - set_uniform(rect_shader, "transform", &transform) + use_shader(cube_shader) + view_mat := lalg.matrix4_translate_f32({0, 0, -5}) + proj_mat := lalg.matrix4_perspective_f32(math.to_radians(f32(45)), f32(viewport[2]) / f32(viewport[3]), 0.01, 1000) + set_uniform(cube_shader, "view", &view_mat) + set_uniform(cube_shader, "projection", &proj_mat) + sin_time01 := math.sin(time) * 0.5 + 0.5 + set_uniform(cube_shader, "myColor", v4{0.5, f32(sin_time01), 0.25, 1.0}) + set_uniform(cube_shader, "alpha", texture_alpha) gl.ActiveTexture(gl.TEXTURE0); gl.BindTexture(gl.TEXTURE_2D, grass_texture) gl.ActiveTexture(gl.TEXTURE1); gl.BindTexture(gl.TEXTURE_2D, face_texture) gl.BindVertexArray(VAOs[0]) - gl.DrawElements(gl.TRIANGLES, len(indices), gl.UNSIGNED_INT, nil) - transform2 := mat4(1) - transform2 *= lalg.matrix4_translate_f32({0.5, 0, 0}) - transform2 *= lalg.matrix4_rotate_f32(f32(-time), {0, 0, 1}) - transform2 *= lalg.matrix4_scale_f32(v3(f32(sin_time01))) - set_uniform(rect_shader, "transform", &transform2) - gl.DrawElements(gl.TRIANGLES, len(indices), gl.UNSIGNED_INT, nil) + for pos, idx in cube_positions { + rotate_by := f32(20 * idx) + if idx % 3 == 0 { + rotate_by += f32(time * 2) + } + model_mat := lalg.matrix4_rotate_f32(rotate_by, {1, 0.3, 0.5}) + model_mat = lalg.matrix4_translate_f32(pos) * model_mat + set_uniform(cube_shader, "model", &model_mat) + + gl.DrawArrays(gl.TRIANGLES, 0, 36) + } use_shader(tri_shader) - set_uniform(tri_shader, "yFactor", f32(sin(time) * 0.5)) + set_uniform(tri_shader, "yFactor", f32(math.sin(time) * 0.5)) gl.BindVertexArray(VAOs[1]) gl.DrawArrays(gl.TRIANGLES, 0, 3) @@ -183,6 +230,7 @@ fb_size_callback :: proc "c" (window: glfw.WindowHandle, width, height: i32) { context = runtime.default_context() gl.Viewport(0, 0, width, height) + gl.GetIntegerv(gl.VIEWPORT, &viewport[0]); render() // Draw while resizing } diff --git a/odinfmt.json b/odinfmt.json index 5583869..85b1377 100644 --- a/odinfmt.json +++ b/odinfmt.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/DanielGavin/ols/master/misc/odinfmt.schema.json", - "character_width": 100, + "character_width": 120, "tabs": true, "tabs_width": 2 } diff --git a/shaders/rect.glsl b/shaders/cube.glsl similarity index 83% rename from shaders/rect.glsl rename to shaders/cube.glsl index 5acb2d9..e5d7e9a 100644 --- a/shaders/rect.glsl +++ b/shaders/cube.glsl @@ -3,13 +3,15 @@ layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aTextureCoord; -uniform mat4 transform; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; out vec2 textureCoord; void main() { - gl_Position = transform * vec4(aPos, 1.0); + gl_Position = projection * view * model * vec4(aPos, 1.0); textureCoord = aTextureCoord; } diff --git a/utils.odin b/utils.odin index 25640a3..698da95 100644 --- a/utils.odin +++ b/utils.odin @@ -8,7 +8,7 @@ import lalg "core:math/linalg" import gl "vendor:OpenGL" load_shader :: proc(name: string) -> (program: u32, success: bool) { - file_name, concat_err := strings.concatenate({name, SHADERS_EXTENSION}) + file_name, concat_err := strings.concatenate({name, ".", SHADERS_EXTENSION}) if concat_err != nil { return 0, false }