From 05aa5178f7b0cf0962d4125a6a0af76a972150f2 Mon Sep 17 00:00:00 2001 From: iurii plugatarov Date: Sun, 18 Aug 2024 20:44:13 +0300 Subject: light --- Makefile | 2 +- res/shaders/colors.fs | 11 +++ res/shaders/colors.vs | 11 +++ res/shaders/light_cube.fs | 7 ++ res/shaders/light_cube.vs | 11 +++ src/main.odin | 233 ++++++++++------------------------------------ src/shader/shader.odin | 12 +++ 7 files changed, 101 insertions(+), 186 deletions(-) create mode 100644 res/shaders/colors.fs create mode 100644 res/shaders/colors.vs create mode 100644 res/shaders/light_cube.fs create mode 100644 res/shaders/light_cube.vs diff --git a/Makefile b/Makefile index 5f97b46..fe271cc 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ release: $(OUT_DIR_RELEASE)/$(PROGRAM_NAME) # Rule for building the debug version $(OUT_DIR_DEBUG)/$(PROGRAM_NAME): $(SRC_DIR)/*.odin @mkdir -p $(OUT_DIR_DEBUG) - $(ODIN) build $(SRC_DIR) -out:$(OUT_DIR_DEBUG)/$(PROGRAM_NAME) --debug + $(ODIN) build $(SRC_DIR) -out:$(OUT_DIR_DEBUG)/$(PROGRAM_NAME) --debug -define:GL_DEBUG=true # Rule for building the release version $(OUT_DIR_RELEASE)/$(PROGRAM_NAME): $(SRC_DIR)/*.odin diff --git a/res/shaders/colors.fs b/res/shaders/colors.fs new file mode 100644 index 0000000..a2b8ff4 --- /dev/null +++ b/res/shaders/colors.fs @@ -0,0 +1,11 @@ +#version 330 core + +out vec4 FragColor; + +uniform vec3 object_color; +uniform vec3 light_color; + +void main() { + FragColor = vec4(light_color * object_color, 1.0); +} + diff --git a/res/shaders/colors.vs b/res/shaders/colors.vs new file mode 100644 index 0000000..63a9758 --- /dev/null +++ b/res/shaders/colors.vs @@ -0,0 +1,11 @@ +#version 330 core + +layout (location = 0) in vec3 a_pos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() { + gl_Position = projection * view * model * vec4(a_pos, 1.0); +} diff --git a/res/shaders/light_cube.fs b/res/shaders/light_cube.fs new file mode 100644 index 0000000..006695a --- /dev/null +++ b/res/shaders/light_cube.fs @@ -0,0 +1,7 @@ +#version 330 core + +out vec4 FragColor; + +void main() { + FragColor = vec4(1.0); +} diff --git a/res/shaders/light_cube.vs b/res/shaders/light_cube.vs new file mode 100644 index 0000000..63a9758 --- /dev/null +++ b/res/shaders/light_cube.vs @@ -0,0 +1,11 @@ +#version 330 core + +layout (location = 0) in vec3 a_pos; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main() { + gl_Position = projection * view * model * vec4(a_pos, 1.0); +} diff --git a/src/main.odin b/src/main.odin index f399fbb..c2c54ef 100644 --- a/src/main.odin +++ b/src/main.odin @@ -27,12 +27,14 @@ SCREEN_WIDTH: f32 : 800.0 SCREEN_HEIGTH: f32 : 600.0 -camera := cam.camera_init(Vec3{0.0, 0.0, 0.3}) +camera := cam.camera_init(Vec3{0.0, 0.0, 3.0}) first_mouse := true last_x: f32 = 800.0 / 2.0 last_y: f32 = 800.0 / 2.0 +light_pos := Vec3{1.2, 1.0, 2.0} + framebuffer_size_callback :: proc "cdecl" (window: glfw.WindowHandle, width, height: i32) { gl.Viewport(0, 0, width, height) } @@ -119,7 +121,18 @@ main :: proc() { glfw.SetScrollCallback(window, mouse_scroll_callback) glfw.SetInputMode(window, glfw.CURSOR, glfw.CURSOR_DISABLED) - shdr, err := shader.shader_init("res/shaders/triangle.vs", "res/shaders/triangle.fs") + light_cube_shader, err := shader.shader_init( + "res/shaders/light_cube.vs", + "res/shaders/light_cube.fs", + ) + if err == shader.SHADER_LOAD_ERROR { + fmt.eprintln("Could not initialize shader") + return + } + + lighting_shader: ^shader.Shader + lighting_shader, err = shader.shader_init("res/shaders/colors.vs", "res/shaders/colors.fs") + if err == shader.SHADER_LOAD_ERROR { fmt.eprintln("Could not initialize shader") return @@ -129,191 +142,116 @@ main :: proc() { -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, } - vbo, vao, texture1, texture2: u32 - gl.GenVertexArrays(1, &vao) + vbo, light_cube_vao, cube_vao: u32 gl.GenBuffers(1, &vbo) - - gl.BindVertexArray(vao) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData( @@ -323,96 +261,22 @@ main :: proc() { gl.STATIC_DRAW, ) - gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 5 * size_of(f32), 0) + gl.GenVertexArrays(1, &cube_vao) + gl.BindVertexArray(cube_vao) + gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * size_of(f32), 0) gl.EnableVertexAttribArray(0) - gl.VertexAttribPointer(1, 2, gl.FLOAT, gl.FALSE, 5 * size_of(f32), 3 * size_of(f32)) - gl.EnableVertexAttribArray(1) - - gl.GenTextures(1, &texture1) - gl.BindTexture(gl.TEXTURE_2D, texture1) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) - - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) - - width, height, nr_channels: libc.int - assert(os.is_file_path("res/images/container.jpg")) - data := image.load("res/images/container.jpg", &width, &height, &nr_channels, 0) - - if data != nil { - gl.TexImage2D( - gl.TEXTURE_2D, - 0, - gl.RGB, - i32(width), - i32(height), - 0, - gl.RGB, - gl.UNSIGNED_BYTE, - data, - ) - gl.GenerateMipmap(gl.TEXTURE_2D) - } else { - fmt.eprintln("Failed to load texture") - return - } - image.image_free(data) - - gl.GenTextures(1, &texture2) - gl.BindTexture(gl.TEXTURE_2D, texture2) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT) - - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) - - image.set_flip_vertically_on_load(1) - - assert(os.is_file_path("res/images/awesomeface.png")) - data = image.load("res/images/awesomeface.png", &width, &height, &nr_channels, 0) - - if data != nil { - gl.TexImage2D( - gl.TEXTURE_2D, - 0, - gl.RGBA, - i32(width), - i32(height), - 0, - gl.RGBA, - gl.UNSIGNED_BYTE, - data, - ) - gl.GenerateMipmap(gl.TEXTURE_2D) - } else { - fmt.eprintln("Failed to load texture") - return - } - image.image_free(data) - shader.use(shdr) - shader.set_value(shdr, cstring("texture1"), 0) - shader.set_value(shdr, cstring("texture2"), 1) + gl.GenVertexArrays(1, &light_cube_vao) + gl.BindVertexArray(light_cube_vao) + gl.BindBuffer(gl.ARRAY_BUFFER, vbo) + gl.VertexAttribPointer(0, 3, gl.FLOAT, gl.FALSE, 3 * size_of(f32), 0) + gl.EnableVertexAttribArray(0) //gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) gl.Enable(gl.DEPTH_TEST) - cube_positions: []linalg.Vector3f32 = { - linalg.Vector3f32{0.0, 0.0, 0.0}, - linalg.Vector3f32{2.0, 5.0, -15.0}, - linalg.Vector3f32{-1.5, -2.2, -2.5}, - linalg.Vector3f32{-3.8, -2.0, -12.3}, - linalg.Vector3f32{2.4, -0.4, -3.5}, - linalg.Vector3f32{-1.7, 3.0, -7.5}, - linalg.Vector3f32{1.3, -2.0, -2.5}, - linalg.Vector3f32{1.5, 2.0, -2.5}, - linalg.Vector3f32{1.5, 0.2, -1.5}, - linalg.Vector3f32{-1.3, 1.0, -1.5}, - } - for !glfw.WindowShouldClose(window) { current_frame: f32 = f32(glfw.GetTime()) delta_time = current_frame - last_frame @@ -420,19 +284,17 @@ main :: proc() { process_input(&window) - gl.ClearColor(0.2, 0.3, 0.3, 1.0) + gl.ClearColor(0.1, 0.1, 0.1, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) - gl.ActiveTexture(gl.TEXTURE0) - gl.BindTexture(gl.TEXTURE_2D, texture1) - gl.ActiveTexture(gl.TEXTURE1) - gl.BindTexture(gl.TEXTURE_2D, texture2) + shader.use(lighting_shader) + object_color := Vec3{1.0, 0.5, 0.31} + light_color := Vec3{1.0, 1.0, 1.0} + shader.set_vec3(lighting_shader, cstring("object_color"), &object_color[0]) + shader.set_vec3(lighting_shader, cstring("light_color"), &light_color[0]) aspect: f32 = 800.0 / 600.0 - - view := cam.get_view_matrix(camera) - projection := linalg.matrix4_perspective_f32( linalg.to_radians(camera.zoom), aspect, @@ -440,35 +302,36 @@ main :: proc() { 100.0, ) - view_location := gl.GetUniformLocation(shdr.id, "view") + view := cam.get_view_matrix(camera) + + view_location := gl.GetUniformLocation(lighting_shader.id, "view") gl.UniformMatrix4fv(view_location, 1, gl.FALSE, &view[0][0]) - projection_location := gl.GetUniformLocation(shdr.id, "projection") + projection_location := gl.GetUniformLocation(lighting_shader.id, "projection") gl.UniformMatrix4fv(projection_location, 1, gl.FALSE, &projection[0][0]) - shader.use(shdr) - - - gl.BindVertexArray(vao) - - for cube_position, i in cube_positions { - model := linalg.matrix4_translate(cube_position) - angle: f32 = linalg.to_radians(20.0 * cast(f32)i) - model *= linalg.matrix4_rotate(angle, linalg.Vector3f32{1.0, 0.3, 0.5}) - + model := linalg.MATRIX4F32_IDENTITY + shader.set_mat4(lighting_shader, cstring("model"), &model[0][0]) - model_location := gl.GetUniformLocation(shdr.id, "model") - gl.UniformMatrix4fv(model_location, 1, gl.FALSE, &model[0][0]) + gl.BindVertexArray(cube_vao) + gl.DrawArrays(gl.TRIANGLES, 0, 36) + shader.use(light_cube_shader) + shader.set_mat4(light_cube_shader, cstring("projection"), &projection[0][0]) + shader.set_mat4(light_cube_shader, cstring("view"), &view[0][0]) - gl.DrawArrays(gl.TRIANGLES, 0, 36) - } + model = linalg.matrix4_translate_f32(light_pos) + model *= linalg.matrix4_scale_f32(Vec3{0.2, 0.2, 0.2}) + shader.set_mat4(light_cube_shader, cstring("model"), &model[0][0]) + gl.BindVertexArray(light_cube_vao) + gl.DrawArrays(gl.TRIANGLES, 0, 36) glfw.SwapBuffers(window) glfw.PollEvents() } - gl.DeleteVertexArrays(1, &vao) + gl.DeleteVertexArrays(1, &light_cube_vao) + gl.DeleteVertexArrays(1, &cube_vao) gl.DeleteBuffers(1, &vbo) } diff --git a/src/shader/shader.odin b/src/shader/shader.odin index 171d7ad..2aa989c 100644 --- a/src/shader/shader.odin +++ b/src/shader/shader.odin @@ -1,5 +1,6 @@ package shader +import "core:math/linalg" import "core:os" import "core:strings" import gl "vendor:OpenGL" @@ -11,6 +12,9 @@ Shader :: struct { SHADER_LOAD_ERROR :: -1 SHADER_OK :: 0 +Vec3 :: linalg.Vector3f32 +Mat4 :: linalg.Matrix4x4f32 + shader_init :: proc(vsp, fsp: string) -> (^Shader, int) { assert(os.is_file_path(vsp)) assert(os.is_file_path(fsp)) @@ -43,6 +47,14 @@ set_f32 :: proc(using shader: ^Shader, name: cstring, value: f32) { gl.Uniform1f(gl.GetUniformLocation(id, name), value) } +set_vec3 :: proc(using shader: ^Shader, name: cstring, value: [^]f32) { + gl.Uniform3fv(gl.GetUniformLocation(id, name), 1, value) +} + +set_mat4 :: proc(using shader: ^Shader, name: cstring, value: [^]f32) { + gl.UniformMatrix4fv(gl.GetUniformLocation(id, name), 1, gl.FALSE, value) +} + set_value :: proc { set_i32, set_f32, -- cgit 1.4.1-2-gfad0