starting on drawing a cube
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Dec 2021 21:10:01 +0000 (15:10 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 16 Dec 2021 21:10:01 +0000 (15:10 -0600)
run_tree/assets/shaders/basic_fragment.glsl [new file with mode: 0644]
run_tree/assets/shaders/basic_vertex.glsl [new file with mode: 0644]
run_tree/lib/onyx_glfw3.so
run_tree/lib/onyx_opengles.so
src/main.onyx

diff --git a/run_tree/assets/shaders/basic_fragment.glsl b/run_tree/assets/shaders/basic_fragment.glsl
new file mode 100644 (file)
index 0000000..f81d312
--- /dev/null
@@ -0,0 +1,12 @@
+#version 300 es
+precision mediump float;
+
+uniform sampler2D u_sampler;
+uniform float     u_sampler_enabled;
+
+in vec2 v_tex;
+
+out vec4 fragColor;
+void main() {
+    fragColor = mix(vec4(1, 1, 1, 1), texture(u_sampler, v_tex), u_sampler_enabled);
+}
diff --git a/run_tree/assets/shaders/basic_vertex.glsl b/run_tree/assets/shaders/basic_vertex.glsl
new file mode 100644 (file)
index 0000000..e8d9f2f
--- /dev/null
@@ -0,0 +1,15 @@
+#version 300 es
+layout(location = 0) in vec3 a_pos;
+layout(location = 1) in vec2 a_tex;
+
+layout(std140) uniform u_matrix_block {
+    mat4 u_view;
+    mat4 u_world;
+};
+
+out vec2 v_tex;
+
+void main() {
+    gl_Position = u_view * u_world * vec4(a_pos, 1);
+    v_tex = a_tex;
+}
index f41064aa2453daa874cc96e54dc8504913ed0b44..f6e354bb1fdade5d43e982e4434db86929f2eaab 100755 (executable)
Binary files a/run_tree/lib/onyx_glfw3.so and b/run_tree/lib/onyx_glfw3.so differ
index 8500f5b362fc0a3c64ab45e1b2259504d236a2d6..71591b0922cef35fce573675c5eda80c5347170c 100755 (executable)
Binary files a/run_tree/lib/onyx_opengles.so and b/run_tree/lib/onyx_opengles.so differ
index 158cfd5476fff89dabf5878820ffb9afc3dbe2d1..5b609e0d776683192cf2f25d02e1d30c67044649 100644 (file)
 use package core
 use package glfw3
 use package opengles
+use package stb_truetype
 
-main :: (args) => {
-    if !glfwInit() {
-        println("Failed to initialize GLFW");
-        os.exit(1);
-    }
 
+window: GLFWwindow_p;
+create_window :: () => {
     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-    window := glfwCreateWindow(800, 600, #cstr "Voxel Shooter");
+    window = glfwCreateWindow(800, 600, #cstr "Voxel Shooter");
+
     glfwMakeContextCurrent(window);
+    glfwSetWindowSizeCallback(window, "on_resize");
+}
+
+#export "on_resize" (window: GLFWwindow_p, width, height: u32) {
+    glViewport(0, 0, width, height);
+    update_view_matrix();
+}
+
+Mesh :: struct {
+    handle: GLuint;
+    verticies: [] f32;
+    indicies:  [] u16;
+}
+
+cube_verticies :: (x, y, z: f32) -> [] GLfloat {
+    vertex_data := GLfloat.[
+        x-0.5, y-0.5, z-0.5,
+        x+0.5, y-0.5, z-0.5,
+        x+0.5, y+0.5, z-0.5,
+        x-0.5, y-0.5, z-0.5,
+        x+0.5, y+0.5, z-0.5,
+        x-0.5, y+0.5, z-0.5,
+
+        x-0.5, y-0.5, z-0.5,
+        x-0.5, y+0.5, z-0.5,
+        x-0.5, y+0.5, z+0.5,
+        x-0.5, y-0.5, z-0.5,
+        x-0.5, y+0.5, z+0.5,
+        x-0.5, y-0.5, z+0.5,
+
+        x-0.5, y-0.5, z-0.5,
+        x-0.5, y+0.5, z+0.5,
+        x+0.5, y+0.5, z+0.5,
+        x-0.5, y-0.5, z-0.5,
+        x+0.5, y+0.5, z+0.5,
+        x+0.5, y-0.5, z-0.5,
+    ];
+
+    return memory.copy_slice(vertex_data);
+}
+
+vao: GLuint;
+matrix_block_buffer: GLuint;
+
+setup_opengl :: () {
     glInit(glfwGetLoadProcAddress());
 
-    while !glfwWindowShouldClose(window) {
-        glClearColor(.2, .2, .2, 1);
-        glClear(GL_COLOR_BUFFER_BIT);
+    compile_shader :: (source: str, type: GLenum) -> GLint {
+        shader := glCreateShader(type);
+        source_data := source.data;
+        source_len  := source.count;
+        glShaderSource(shader, 1, ^source_data, ^source_len);
+        glCompileShader(shader);
+
+        success: GLint;
+        if glGetShaderiv(shader, GL_COMPILE_STATUS, ^success); success == GL_FALSE {
+            buf_data: [1024] u8;
+            buf := str.{ ~~buf_data, 0 };
+            glGetShaderInfoLog(shader, 1024, ^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;
+    }
+
+    vertex_shader := os.get_contents("assets/shaders/basic_vertex.glsl");    
+    fragment_shader := os.get_contents("assets/shaders/basic_fragment.glsl");
+    vs := compile_shader(vertex_shader, GL_VERTEX_SHADER);
+    fs := compile_shader(fragment_shader, GL_FRAGMENT_SHADER);
+
+    prog := link_program(vs, fs);
+    glUseProgram(prog);
+
+    matrix: [32] GLfloat;
+    glGenBuffers(1, ^matrix_block_buffer);
+    glBindBuffer(GL_UNIFORM_BUFFER, matrix_block_buffer);
+    glBufferData(GL_UNIFORM_BUFFER, sizeof f32 * (16 + 16), ^matrix, GL_DYNAMIC_DRAW);
+    glBindBuffer(GL_UNIFORM_BUFFER, -1);
+
+    glBindBufferBase(GL_UNIFORM_BUFFER, 0, matrix_block_buffer);
 
+    matrix_block_index := glGetUniformBlockIndex(prog, #cstr "u_matrix_block");
+    glUniformBlockBinding(prog, matrix_block_index, 0);
+
+    glGenVertexArrays(1, ^vao);
+    glBindVertexArray(vao);
+
+    vbo: GLuint;
+    glGenBuffers(1, ^vbo);
+    glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+    vertex_data := cube_verticies(0, 0, -4);
+    glBufferData(GL_ARRAY_BUFFER, sizeof GLfloat * vertex_data.count, vertex_data.data, GL_STATIC_DRAW);
+
+    glEnableVertexAttribArray(0);
+    glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof GLfloat, ~~0);
+
+    glBindVertexArray(-1);
+    update_view_matrix();
+    update_world_matrix();
+}
+
+update_view_matrix :: () {
+    fov := 75 * math.PI / 180;
+    fov = math.clamp(fov, 0, math.PI - 0.01f);
+
+    width, height: u32;
+    glfwGetWindowSize(window, ^width, ^height);
+    ar := cast(f32) width / cast(f32) height;
+    z_near := 0.01f;
+    z_far  := 100.0f;
+    z_range := z_far - z_near;
+    tan_half_fov := math.sin(fov / 2) / math.cos(fov / 2);
+
+    matrix := GLfloat.[
+        1 / (tan_half_fov * ar), 0, 0, 0,
+        0, 1 / (tan_half_fov), 0, 0,
+        0, 0, (-z_far) / z_range, -1,
+        0, 0, -(z_far*z_near)/z_range, 0,
+    ];
+
+    glBindBuffer(GL_UNIFORM_BUFFER, matrix_block_buffer);
+    glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof typeof matrix, ^matrix);
+    glBindBuffer(GL_UNIFORM_BUFFER, -1);
+}
+
+update_world_matrix :: () {
+    #persist t := 0.0f;
+    t += 0.01;
+
+    c := math.cos(t);
+    s := math.sin(t);
+    matrix := GLfloat.[
+        c, 0, s, 0,
+        0, 1, 0, 0,
+        -s, 0, c, 0,
+        0, 0, 0, 1,
+    ];
+
+    glBindBuffer(GL_UNIFORM_BUFFER, matrix_block_buffer);
+    glBufferSubData(GL_UNIFORM_BUFFER, 16 * sizeof f32, sizeof typeof matrix, ^matrix);
+    glBindBuffer(GL_UNIFORM_BUFFER, -1);
+}
+
+update :: (dt: f32) {
+    update_world_matrix();
+}
+
+draw :: () {
+    glClearColor(.2, .2, .2, 1);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glBindVertexArray(vao);
+    glDrawArrays(GL_TRIANGLES, 0, 18);
+    glBindVertexArray(-1);
+
+    glfwSwapBuffers(window);
+}
+
+main_loop :: () {
+    while !glfwWindowShouldClose(window) {
         glfwPollEvents();
-        glfwSwapBuffers(window);
+
+        update(1.0f / 60);
+        draw();
     }
-}
\ No newline at end of file
+}
+
+main :: (args) => {
+    if !glfwInit() {
+        println("Failed to initialize GLFW");
+        os.exit(1);
+    }
+
+    create_window();
+    setup_opengl();
+    main_loop();
+}