From c467a8b2a86ac689f605bf3d7d28fc3bb0077208 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Tue, 22 Feb 2022 16:18:30 -0600 Subject: [PATCH] pulled more new code from other project; not doing that again... --- src/build.onyx | 4 +- src/chunk.onyx | 2 +- src/gfx/immediate.onyx | 14 +++- src/gfx/shader.onyx | 53 ++++++------- src/gfx/texture.onyx | 39 ++++++++-- src/logger.onyx | 35 +++++++++ src/shader.onyx | 171 ----------------------------------------- 7 files changed, 108 insertions(+), 210 deletions(-) create mode 100644 src/logger.onyx delete mode 100644 src/shader.onyx diff --git a/src/build.onyx b/src/build.onyx index 3dd0e44..2549a3e 100644 --- a/src/build.onyx +++ b/src/build.onyx @@ -11,10 +11,10 @@ #load "chunk" #load "config" #load "input" +#load "logger" #load "main" #load "physics" #load "player" -#load "shader" #load "utils" #load "vecmath" #load "world" @@ -24,7 +24,7 @@ #load "gfx/font" #load "gfx/immediate" #load "gfx/mesh" -// #load "gfx/shader" +#load "gfx/shader" #load "gfx/texture" #load "gfx/ui" diff --git a/src/chunk.onyx b/src/chunk.onyx index aeaa5e0..c076957 100644 --- a/src/chunk.onyx +++ b/src/chunk.onyx @@ -187,7 +187,7 @@ chunk_destroy_mesh :: (use chunk: ^Chunk) { #local block_texture: Texture; chunk_draw :: (chunk: ^Chunk) { if block_texture.filename.data == null { - block_texture = texture_make(#cstr "assets/textures/block.png"); + block_texture', _ := texture_lookup("assets/textures/block.png"); } texture_use(^block_texture); diff --git a/src/gfx/immediate.onyx b/src/gfx/immediate.onyx index 23dd4eb..7c6b5e6 100644 --- a/src/gfx/immediate.onyx +++ b/src/gfx/immediate.onyx @@ -33,6 +33,7 @@ immediate_flush :: () { vertex_count = 0; rendering_type = .Plain; + immediate_mesh.primitive = GL_TRIANGLES; } immediate_clear :: (color: Color) { @@ -51,6 +52,16 @@ immediate_vertex :: (x, y: f32, t_x := 0.0f, t_y := 0.0f) { vertex_data[vertex_count] = .{ .{x, y}, .{t_x, t_y}, immediate_color }; } +immediate_line :: (x1, y1, x2, y2: f32) { + if vertex_count >= Maximum_Vertex_Count do immediate_flush(); + set_rendering_type(.Line); + immediate_mesh.primitive = GL_LINES; + + vertex_data[vertex_count + 0] = .{ .{x1, y1}, .{0, 0}, immediate_color }; + vertex_data[vertex_count + 1] = .{ .{x2, y2}, .{0, 0}, immediate_color }; + vertex_count += 2; +} + immediate_triangle :: (x1, x2, x3: Vector2) { if vertex_count + 3 > Maximum_Vertex_Count do immediate_flush(); set_rendering_type(.Plain); @@ -120,7 +131,7 @@ immediate_push_scissor :: (x, y, w, h: f32) { scissors << .{x, y, w, h}; glEnable(GL_SCISSOR_TEST); - glScissor(~~x, ~~(window_height - (y + h)), ~~w, ~~h); + glScissor(~~x, ~~(window_height - ~~(y + h)), ~~w, ~~h); } immediate_pop_scissor :: () { @@ -162,6 +173,7 @@ Immediate_Vertex :: struct { Rendering_Type :: enum { Plain; + Line; Image; } rendering_type := Rendering_Type.Plain; diff --git a/src/gfx/shader.onyx b/src/gfx/shader.onyx index 246c3d1..8e553c5 100644 --- a/src/gfx/shader.onyx +++ b/src/gfx/shader.onyx @@ -18,7 +18,7 @@ shaders_init :: () { glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * 16, null, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * (16 + 16), null, GL_DYNAMIC_DRAW); + glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * (16 + 16 + 16), null, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, -1); @@ -26,10 +26,10 @@ shaders_init :: () { glBindBufferBase(GL_UNIFORM_BUFFER, WORLD_MATRIX_BLOCK, world_matrix_block_buffer); } -shader_make :: (shader_path: str) -> Shader { - shader_source := os.get_contents(shader_path); - vs := compile_shader(shader_source, GL_VERTEX_SHADER); - fs := compile_shader(shader_source, GL_FRAGMENT_SHADER); +shader_make :: (path: str) -> Shader { + shader := os.get_contents(path); + vs := compile_shader(shader, GL_VERTEX_SHADER); + fs := compile_shader(shader, GL_FRAGMENT_SHADER); prog := link_program(vs, fs); @@ -75,51 +75,44 @@ shader_set_uniform :: (shader: Shader, uniform: cstr, value: $T) { } update_view_matrix :: () { - matrix : [16] f32; - top := 0.0f; - left := 0.0f; - right := cast(f32) window_width; - bottom := cast(f32) window_height; - far := 10.0f; - near := 0f; - - matrix[0] = 2 / (right - left); - matrix[5] = 2 / (top - bottom); - matrix[10] = -2 / (far - near); - matrix[12] = -(right + left) / (right - left); - matrix[13] = -(top + bottom) / (top - bottom); - matrix[14] = -(far + near) / (far - near); - matrix[15] = 1; + view_mat: [16] f32; + camera_get_view_matrix(^camera, view_mat); - glBindBuffer(GL_UNIFORM_BUFFER, window_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof matrix, ^matrix); + glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof view_mat, ^view_mat); glBindBuffer(GL_UNIFORM_BUFFER, -1); } update_world_matrix :: () { world_mat: [16] f32; - world_mat[0] = 1; - world_mat[5] = 1; - world_mat[10] = 1; - world_mat[15] = 1; + camera_get_world_matrix(^camera, world_mat); glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof world_mat, ^world_mat); + glBufferSubData(GL_UNIFORM_BUFFER, 16 * sizeof f32, sizeof typeof world_mat, ^world_mat); + glBindBuffer(GL_UNIFORM_BUFFER, -1); +} + +update_window_matrix :: () { + window_mat: [16] f32; + camera_get_window_matrix(^camera, window_mat); + + glBindBuffer(GL_UNIFORM_BUFFER, window_matrix_block_buffer); + glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof window_mat, ^window_mat); glBindBuffer(GL_UNIFORM_BUFFER, -1); } -update_model_matrix :: (v: Vector2) { +update_model_matrix :: (v: Vector3) { model_mat: [16] f32; model_mat[0] = 1; model_mat[5] = 1; model_mat[10] = 1; model_mat[12] = v.x; model_mat[13] = v.y; - model_mat[14] = 0; + model_mat[14] = v.z; model_mat[15] = 1; glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 16 * sizeof f32, sizeof typeof model_mat, ^model_mat); + glBufferSubData(GL_UNIFORM_BUFFER, 32 * sizeof f32, sizeof typeof model_mat, ^model_mat); glBindBuffer(GL_UNIFORM_BUFFER, -1); } diff --git a/src/gfx/texture.onyx b/src/gfx/texture.onyx index 5d51168..2ceb980 100644 --- a/src/gfx/texture.onyx +++ b/src/gfx/texture.onyx @@ -1,19 +1,41 @@ use package core +use package core.intrinsics.onyx { __zero_value as Zero } use package opengles use package stb_image +#local texture_cache: Map(str, Texture); + Texture :: struct { texture: GLint; width, height, channels: i32; filename: str; } -texture_make :: (path: cstr) -> Texture { +texture_lookup :: #match {} +#match texture_lookup (filename: str) -> (Texture, bool) { + if texture_cache->has(filename) { + return texture_cache[filename], true; + } + + buffer: [512] u8; + memory.copy(~~ buffer, filename.data, math.min(filename.count, 511)); + return texture_lookup(cast(cstr) buffer); +} + +#match texture_lookup (path: cstr) -> (Texture, bool) { + filename := string.from_cstr(path); + if texture_cache->has(filename) { + return texture_cache[filename], true; + } + tex: Texture; - tex.filename = path |> string.from_cstr(); + tex.filename = filename; pixels := stbi_load(path, ^tex.width, ^tex.height, ^tex.channels, 4); - assert(pixels != null, "Failed to load texture."); + if pixels == null { + debug_log(.Warning, "Failed to load texture: {}", filename); + return Zero(Texture), false; + } defer stbi_image_free(pixels); glGenTextures(1, ^tex.texture); @@ -28,11 +50,18 @@ texture_make :: (path: cstr) -> Texture { glBindTexture(GL_TEXTURE_2D, 0); - return tex; + // This assumes that the filename data is going to be persistant forever. + // Not a great assumption to make but is it really worth copying it? + texture_cache[filename] = tex; + debug_log(.Info, "Loaded texture: {}", filename); + return tex, true; +} + +texture_free :: (use tex: ^Texture) { + glDeleteTextures(1, ^texture); } texture_use :: (use tex: ^Texture, texture_binding := 0) { glActiveTexture(GL_TEXTURE0 + texture_binding); glBindTexture(GL_TEXTURE_2D, texture); } - diff --git a/src/logger.onyx b/src/logger.onyx new file mode 100644 index 0000000..529ddee --- /dev/null +++ b/src/logger.onyx @@ -0,0 +1,35 @@ +// +// This may become an in-game or external file logger in the future, +// but for now this is just for logging to the command line. + +use package core + +Log_Level :: enum { + Debug; + Info; + Warning; + Error; + Critical; +} + +debug_log :: (level: Log_Level, format: str, args: ..any) { + debug_log_va(level, format, ~~args); +} + +debug_log_va :: (level: Log_Level, format: str, args: [] any) { + buf: [2048] u8; + output := conv.format_va(buf, format, args); + printf("[{}] {}\n", level_string(level), output); +} + +#local level_string :: (level: Log_Level) => { + switch level { + case .Debug do return "DEBUG"; + case .Info do return "INFO "; + case .Warning do return "WARN "; + case .Error do return "ERROR"; + case .Critical do return "CRIT "; + } + + return " "; +} diff --git a/src/shader.onyx b/src/shader.onyx deleted file mode 100644 index 8e553c5..0000000 --- a/src/shader.onyx +++ /dev/null @@ -1,171 +0,0 @@ - -use package core -use package opengles - -Shader :: struct { - vs, fs: GLuint; - prog: GLuint; -} - -window_matrix_block_buffer: GLuint; -world_matrix_block_buffer: GLuint; - -shaders_init :: () { - glGenBuffers(1, ^window_matrix_block_buffer); - glGenBuffers(1, ^world_matrix_block_buffer); - - glBindBuffer(GL_UNIFORM_BUFFER, window_matrix_block_buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * 16, null, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * (16 + 16 + 16), null, GL_DYNAMIC_DRAW); - - glBindBuffer(GL_UNIFORM_BUFFER, -1); - - glBindBufferBase(GL_UNIFORM_BUFFER, WINDOW_MATRIX_BLOCK, window_matrix_block_buffer); - glBindBufferBase(GL_UNIFORM_BUFFER, WORLD_MATRIX_BLOCK, world_matrix_block_buffer); -} - -shader_make :: (path: str) -> Shader { - shader := os.get_contents(path); - vs := compile_shader(shader, GL_VERTEX_SHADER); - fs := compile_shader(shader, GL_FRAGMENT_SHADER); - - prog := link_program(vs, fs); - - return Shader.{vs, fs, prog}; -} - -shader_use :: (shader: Shader) { - glUseProgram(shader.prog); -} - -#local { - WINDOW_MATRIX_BLOCK :: 0; - WORLD_MATRIX_BLOCK :: 1; -} - -shader_link_window_matrix_block :: (use shader: Shader) { - matrix_block_index := glGetUniformBlockIndex(prog, #cstr "u_window_matrix_block"); - glUniformBlockBinding(prog, matrix_block_index, WINDOW_MATRIX_BLOCK); -} - -shader_link_world_matrix_block :: (use shader: Shader) { - matrix_block_index := glGetUniformBlockIndex(prog, #cstr "u_world_matrix_block"); - glUniformBlockBinding(prog, matrix_block_index, WORLD_MATRIX_BLOCK); -} - -shader_set_uniform :: (shader: Shader, uniform: cstr, value: $T) { - glUseProgram(shader.prog); - location := glGetUniformLocation(shader.prog, uniform); - - set_uniform_internal(location, value); - - set_uniform_internal :: #match { - macro (location: GLint, value: u32) do glUniform1i(location, value); , - macro (location: GLint, value: f32) do glUniform1f(location, value); , - macro (location: GLint, value: Vector3) do glUniform3f(location, value.x, value.y, value.z); , - macro (location: GLint, value: Color) do glUniform4f(location, value.r, value.g, value.b, value.a); , - - macro (location: GLint, value: $T) { - buffer: [1024] u8; - assert(false, conv.format(buffer, "Bad shader_set_uniform case: {}", T)); - } - } -} - -update_view_matrix :: () { - view_mat: [16] f32; - camera_get_view_matrix(^camera, view_mat); - - glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof view_mat, ^view_mat); - glBindBuffer(GL_UNIFORM_BUFFER, -1); -} - -update_world_matrix :: () { - world_mat: [16] f32; - camera_get_world_matrix(^camera, world_mat); - - glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 16 * sizeof f32, sizeof typeof world_mat, ^world_mat); - glBindBuffer(GL_UNIFORM_BUFFER, -1); -} - -update_window_matrix :: () { - window_mat: [16] f32; - camera_get_window_matrix(^camera, window_mat); - - glBindBuffer(GL_UNIFORM_BUFFER, window_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof window_mat, ^window_mat); - glBindBuffer(GL_UNIFORM_BUFFER, -1); -} - -update_model_matrix :: (v: Vector3) { - model_mat: [16] f32; - model_mat[0] = 1; - model_mat[5] = 1; - model_mat[10] = 1; - model_mat[12] = v.x; - model_mat[13] = v.y; - model_mat[14] = v.z; - model_mat[15] = 1; - - glBindBuffer(GL_UNIFORM_BUFFER, world_matrix_block_buffer); - glBufferSubData(GL_UNIFORM_BUFFER, 32 * sizeof f32, sizeof typeof model_mat, ^model_mat); - glBindBuffer(GL_UNIFORM_BUFFER, -1); -} - - -#local { - compile_shader :: (source: str, type: GLenum) -> GLint { - shader := glCreateShader(type); - - #persist VERTEX_HEADER := """ -#version 300 es -#define VERTEX_SHADER 1 -#define COMM out - """; - - #persist FRAGMENT_HEADER := """ -#version 300 es -#define FRAGMENT_SHADER 1 -#define COMM in - """; - - header := VERTEX_HEADER if type == GL_VERTEX_SHADER else FRAGMENT_HEADER; - sources : [] ^u8 = .[ header.data, source.data ]; - source_lens : [] i32 = .[ header.count, source.count ]; - - glShaderSource(shader, 2, sources.data, source_lens.data); - glCompileShader(shader); - - success: GLint; - if glGetShaderiv(shader, GL_COMPILE_STATUS, ^success); success == GL_FALSE { - buf_data: [2048] u8; - buf := str.{ ~~buf_data, 0 }; - glGetShaderInfoLog(shader, 2048, ^buf.count, buf.data); - println(buf); - } - - return shader; - } - - link_program :: (vertex_shader, fragment_shader: GLint) -> GLuint { - prog := glCreateProgram(); - glAttachShader(prog, vertex_shader); - glAttachShader(prog, fragment_shader); - glLinkProgram(prog); - - success: GLint; - if glGetProgramiv(prog, GL_LINK_STATUS, ^success); success == GL_FALSE { - buf_data: [1024] u8; - buf := str.{ ~~buf_data, 0 }; - glGetProgramInfoLog(prog, 1024, ^buf.count, buf.data); - println(buf); - } - - return prog; - } -} - -- 2.25.1