diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-02-19 22:26:48 +0500 |
commit | f9ad6fa902c1167d7622ee7af2617d14b62bee21 (patch) | |
tree | 9d78792cf360ed871616a9ea66c4237018292aa7 /advanced_lighting/4.normal_mapping/normal_mapping.c | |
parent | 926cbd0d49890772f911e6a6bedb7835605ced89 (diff) |
quite a lot of changes that I, of course, are not going to describe;)
Diffstat (limited to 'advanced_lighting/4.normal_mapping/normal_mapping.c')
-rw-r--r-- | advanced_lighting/4.normal_mapping/normal_mapping.c | 521 |
1 files changed, 242 insertions, 279 deletions
diff --git a/advanced_lighting/4.normal_mapping/normal_mapping.c b/advanced_lighting/4.normal_mapping/normal_mapping.c index 1d65b49..980f4a0 100644 --- a/advanced_lighting/4.normal_mapping/normal_mapping.c +++ b/advanced_lighting/4.normal_mapping/normal_mapping.c @@ -1,288 +1,251 @@ -#include "pwyazh.h" - #include "GL/glew.h" #include "GLFW/glfw3.h" +#include "pwyazh.h" #include "pwyazh_GL.h" #include "common.h" -static S32 global_screen_width = 800, global_screen_height = 600; -static Input global_input; -static B32 first_mouse = 1; - -void -resize_callback(GLFWwindow* window, int width, int height) -{ - global_screen_width = width; - global_screen_height = height; - glViewport(0, 0, global_screen_width, global_screen_height); -} - -void -cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) -{ - if (first_mouse) - { - global_input.last_mouse_pos = v2f(xpos, ypos); - first_mouse = 0; - } - global_input.mouse_offset = v2f(global_input.mouse_offset.x+((F32)xpos-global_input.last_mouse_pos.x), - global_input.mouse_offset.y+((F32)ypos-global_input.last_mouse_pos.y)); - global_input.last_mouse_pos = v2f((F32)xpos, (F32)ypos); -} - -void -render_scene(U32 shader, Mesh *cube) -{ - MAT4 model; - - model = mat4_identity(); - model = mat4_make_scale(v3f(5.0f, 5.0f, 5.0f)); - shader_set_mat4fv(shader, "model", model); - glDisable(GL_CULL_FACE); - shader_set_1i(shader, "reverse_normals", 1); - mesh_draw(cube); - shader_set_1i(shader, "reverse_normals", 0); - glEnable(GL_CULL_FACE); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(0.0f, 1.5f, 0.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.5f, 0.5f, 0.5f)); - model = mat4_translate(model, v3f(2.0f, 0.0f, 1.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); - - model = mat4_identity(); - model = mat4_make_scale(v3f(0.25f, 0.25f, 0.25f)); - model = mat4_rotate_angles(model, v3f(60.0f, 0.0f, 0.0f)); - model = mat4_translate(model, v3f(-1.0f, 0.0f, 2.0f)); - shader_set_mat4fv(shader, "model", model); - mesh_draw(cube); -} - -int -main(void) +int main(void) { - GLFWwindow *window; - Arena *arena; - State state; - Mesh *cube; - F64 time, last_time; - V3F light_pos; - MAT4 shadow_transforms[6]; - MAT4 proj, view; - - glfwSetErrorCallback(error_callback); - - if (glfwInit() == GLFW_FALSE) - return(1); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_SAMPLES, 4); - window = glfwCreateWindow(global_screen_width, global_screen_height, "Point shadows", 0, 0); - if (!window) - goto error; - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - glfwSetWindowSizeCallback(window, resize_callback); - glfwSetCursorPosCallback(window, cursor_pos_callback); - - glfwMakeContextCurrent(window); - - if (glewInit() != GLEW_OK) - goto error; - - glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); - - /* NOTE(pryazha): Init */ - arena = arena_alloc(Megabytes(64)); - - state.camera = (Camera){ - .pos = v3f(0.0f, 1.0f, 3.0f), - .fovx = 100.0f, - .near = 0.1f, - .far = 100.0f, - .yaw = 0.0f, - .pitch = 0.0f - }; - V3F camera_dp = v3f_zero(); - /* light_pos = v3f(-2.0f, 4.0f, -2.0f); */ - light_pos = v3f_zero(); - - /* NOTE(pryazha): Meshes */ - cube = mesh_load_obj(arena, "../../data/models/cube.obj"); - - F32 quad_vertices[] = { - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, - -1.0f, 1.0f, 0.0f, 0.0f, 1.0f - }; - U32 quad_vao, vbo; - glGenVertexArrays(1, &quad_vao); - glBindVertexArray(quad_vao); - glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(F32), (void *)(3*sizeof(F32))); - glBindVertexArray(0); - - /* NOTE(pryazha): Shaders */ - U32 depth_shader = create_shader_program_geom("shaders/depth.vs", - "shaders/depth.fs", - "shaders/depth.gs"); - U32 shadow_shader = create_shader_program("shaders/shadow.vs", "shaders/shadow.fs"); - - glUseProgram(shadow_shader); - shader_set_1i(shadow_shader, "diffuse_texture", 0); - shader_set_1i(shadow_shader, "depth_cubemap", 1); - glUseProgram(0); - - U32 wood_texture = load_texture_gamma("../../data/textures/wood.png", 0); - - /* NOTE(pryazha): Depth framebuffer init */ - U32 depth_cubemap_fbo, depth_cubemap; - U32 shadow_width = 1024, shadow_height = 1024; - glGenFramebuffers(1, &depth_cubemap_fbo); - glGenTextures(1, &depth_cubemap); - glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); - for (U32 cubemap_side = 0; cubemap_side < 6; ++cubemap_side) - glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+cubemap_side, 0, GL_DEPTH_COMPONENT, - shadow_width, shadow_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER); - glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_cubemap, 0); - glDrawBuffer(GL_NONE); - glReadBuffer(GL_NONE); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - fprintf(stderr, "[ERROR]: Failed to complete depth map framebuffer.\n"); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - last_time = glfwGetTime(); - - while (!glfwWindowShouldClose(window)) - { - glfwPollEvents(); - - /* NOTE(pryazha): For now it's easier to write all of the logic in the main loop */ - - /* NOTE(pryazha): Update */ - process_glfw_keyboard(window, &global_input); - - if (key_first_press(global_input.exit)) - glfwSetWindowShouldClose(window, GLFW_TRUE); - - F32 x, y, z, angular_speed, radius; - V3F camera_dv; - - camera_dv = get_dv_camera_first_person(&global_input, &state.camera, - 1.0f, state.dt); - if (key_is_pressed(global_input.action_up)) - camera_dv = v3f_scalef(camera_dv, 3.0f); - camera_dp = v3f_add(camera_dp, camera_dv); - camera_dp = v3f_scalef(camera_dp, 0.8f); - state.camera.pos = v3f_add(state.camera.pos, camera_dp); - - F32 sensitivity = 0.1f; - global_input.mouse_offset = v2f_scalef(global_input.mouse_offset, sensitivity); - state.camera.yaw += global_input.mouse_offset.x; - state.camera.pitch += global_input.mouse_offset.y; - if (state.camera.pitch > 89.0f) - state.camera.pitch = 89.0f; - if (state.camera.pitch < -89.0f) - state.camera.pitch = -89.0f; - - input_update_last_state(&global_input); - - angular_speed = 1.0f; - radius = 4.0f; - x = f32_sin(time*angular_speed)*radius; - y = f32_sin(time*angular_speed)*radius; - z = f32_cos(time*angular_speed)*radius; - - light_pos = v3f(x, y, z); - - /* NOTE(pryazha): Render */ - - /* NOTE(pryazha): Render the depth cubemap */ - F32 fovx, aspect, near, far; - fovx = 90.0f; - aspect = (F32)shadow_width/(F32)shadow_height; - near = 1.0f; - far = 25.0f; - proj = perspective(fovx, aspect, near, far); - shadow_transforms[0] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* right */ - shadow_transforms[1] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f(-1.0f, 0.0f, 0.0f)), v3f(0.0f, -1.0f, 0.0f))); /* left */ - shadow_transforms[2] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 1.0f, 0.0f)), v3f(0.0f, 0.0f, 1.0f))); /* top */ - shadow_transforms[3] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, -1.0f, 0.0f)), v3f(0.0f, 0.0f, -1.0f))); /* bottom */ - shadow_transforms[4] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, 1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* near */ - shadow_transforms[5] = mat4_mul(proj, look_at(light_pos, v3f_add(light_pos, v3f( 0.0f, 0.0f, -1.0f)), v3f(0.0f, -1.0f, 0.0f))); /* far */ - glViewport(0, 0, shadow_width, shadow_height); - glBindFramebuffer(GL_FRAMEBUFFER, depth_cubemap_fbo); - glClear(GL_DEPTH_BUFFER_BIT); - glUseProgram(depth_shader); - shader_set_1f(depth_shader, "far", far); - shader_set_3fv(depth_shader, "light_pos", light_pos); - for (U32 i = 0; i < 6; ++i) - { - char uniform_name[256]; - snprintf(uniform_name, 256, "shadow_transforms[%d]", i); - shader_set_mat4fv(depth_shader, uniform_name, shadow_transforms[i]); - } - render_scene(depth_shader, cube); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - /* NOTE(pryazha): Render the scene as normal */ - glViewport(0, 0, global_screen_width, global_screen_height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glUseProgram(shadow_shader); - - aspect = (F32)global_screen_width/(F32)global_screen_height; - proj = perspective(state.camera.fovx, aspect, state.camera.near, state.camera.far); - view = get_view_matrix(&state.camera); - - shader_set_mat4fv(shadow_shader, "projection", proj); - shader_set_mat4fv(shadow_shader, "view", view); - shader_set_3fv(shadow_shader, "light_pos", light_pos); - shader_set_3fv(shadow_shader, "view_pos", state.camera.pos); - shader_set_1f(shadow_shader, "far", far); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, wood_texture); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_CUBE_MAP, depth_cubemap); - render_scene(shadow_shader, cube); - - glfwSwapBuffers(window); - - time = glfwGetTime(); - state.dt = time-last_time; - last_time = time; - } - - glfwTerminate(); - return(0); - - error: - glfwTerminate(); - return(1); + GLFWwindow *window; + State state; + Input input; + F64 time, last_time; + V3F light_pos; + MAT4 proj, view, model; + F32 aspect, angle = 0.0f; + Mesh *cube = 0; + Arena *arena = 0; + S32 width, height; + + glfwSetErrorCallback(error_callback); + + if (glfwInit() == GLFW_FALSE) + return(1); + + width = 800; + height = 600; + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_SAMPLES, 4); + window = glfwCreateWindow(width, height, "Point shadows", 0, 0); + if (!window) + goto error; + + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + glfwMakeContextCurrent(window); + + if (glewInit() != GLEW_OK) + goto error; + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + + /* NOTE(pryazha): Init */ + arena = arena_alloc(Kilobytes(4)); + + state.camera = (Camera){ v3f(0.0f, 1.0f, 3.0f), 100.0f, 0.1f, 100.0f, 0.0f, 0.0f }; + V3F camera_dp = v3f_zero(); + F32 x, y, z; + + /* NOTE(pryazha): Meshes */ + cube = mesh_load_obj(arena, "../../data/models/cube.obj"); + + /* Positions */ + V3F p1 = v3f(-1.0f, 1.0f, 0.0f); + V3F p2 = v3f(-1.0f, -1.0f, 0.0f); + V3F p3 = v3f(1.0f, -1.0f, 0.0f); + V3F p4 = v3f(1.0f, 1.0f, 0.0f); + /* Texture ccoordinates */ + V2F uv1 = v2f(0.0f, 1.0f); + V2F uv2 = v2f(0.0f, 0.0f); + V2F uv3 = v2f(1.0f, 0.0f); + V2F uv4 = v2f(1.0f, 1.0f); + /* Normal vector */ + V3F nm = v3f(0.0f, 0.0f, 1.0f); + + V3F edge1, edge2; + V2F duv1, duv2; + F32 f; + V3F t1, bit1, t2, bit2; + + edge1 = v3f_sub(p2, p1); + edge2 = v3f_sub(p3, p1); + duv1 = v2f_sub(uv2, uv1); + duv2 = v2f_sub(uv3, uv1); + + f = 1.0f/(duv1.x*duv2.y-duv2.x*duv1.y); + + t1.x = f*(duv2.y*edge1.x-duv1.y*edge2.x); + t1.y = f*(duv2.y*edge1.y-duv1.y*edge2.y); + t1.z = f*(duv2.y*edge1.z-duv1.y*edge2.z); + + bit1.x = f*(-duv2.x*edge1.x+duv1.x*edge2.x); + bit1.y = f*(-duv2.x*edge1.y+duv1.x*edge2.y); + bit1.z = f*(-duv2.x*edge1.z+duv1.x*edge2.z); + + edge1 = v3f_sub(p3, p1); + edge2 = v3f_sub(p4, p1); + duv1 = v2f_sub(uv3, uv1); + duv2 = v2f_sub(uv4, uv1); + + f = 1.0f/(duv1.x*duv2.y-duv2.x*duv1.y); + + t2.x = f*(duv2.y*edge1.x-duv1.y*edge2.x); + t2.y = f*(duv2.y*edge1.y-duv1.y*edge2.y); + t2.z = f*(duv2.y*edge1.z-duv1.y*edge2.z); + + bit2.x = f*(-duv2.x*edge1.x+duv1.x*edge2.x); + bit2.y = f*(-duv2.x*edge1.y+duv1.x*edge2.y); + bit2.z = f*(-duv2.x*edge1.z+duv1.x*edge2.z); + + F32 quad_vertices[] = { + p1.x, p1.y, p1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + p2.x, p2.y, p2.z, nm.x, nm.y, nm.z, uv2.x, uv2.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + p3.x, p3.y, p3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, t1.x, t1.y, t1.z, bit1.x, bit1.y, bit1.z, + + p1.x, p1.y, p1.z, nm.x, nm.y, nm.z, uv1.x, uv1.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z, + p3.x, p3.y, p3.z, nm.x, nm.y, nm.z, uv3.x, uv3.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z, + p4.x, p4.y, p4.z, nm.x, nm.y, nm.z, uv4.x, uv4.y, t2.x, t2.y, t2.z, bit2.x, bit2.y, bit2.z + }; + U32 quad_vao, vbo; + glGenVertexArrays(1, &quad_vao); + glBindVertexArray(quad_vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(quad_vertices), quad_vertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(3*sizeof(F32))); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(6*sizeof(F32))); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(8*sizeof(F32))); + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14*sizeof(F32), (void *)(11*sizeof(F32))); + glBindVertexArray(0); + + /* NOTE(pryazha): Shaders */ + U32 normal_map_shader = create_shader_program("shaders/normal_map.vert", + "shaders/normal_map.frag"); + U32 normals_debug_shader = create_shader_program_geom("shaders/normals_debug.vert", + "shaders/normals_debug.frag", + "shaders/normals_debug.geom"); + U32 color_shader = create_shader_program("shaders/color.vert", + "shaders/color.frag"); + + glUseProgram(normal_map_shader); + shader_set_1i(normal_map_shader, "diffuse_texture", 0); + shader_set_1i(normal_map_shader, "normal_map", 1); + glUseProgram(0); + + U32 brickwall_diffuse_texture = load_texture("../../data/textures/brickwall.jpg"); + U32 brickwall_normal_texture = load_texture("../../data/textures/brickwall_normal.jpg"); + + last_time = glfwGetTime(); + + while (!glfwWindowShouldClose(window)) { + glfwPollEvents(); + + /* NOTE(pryazha): For now it's easier to write all of the logic in the main loop */ + + /* NOTE(pryazha): Update */ + glfwGetFramebufferSize(window, &width, &height); + process_glfw_keyboard(window, &input); + process_glfw_mouse_pos(window, &input); + + if (key_first_press(input.exit)) + glfwSetWindowShouldClose(window, GLFW_TRUE); + + F32 speed = 2.0f; + V3F dv = get_dv_camera_first_person(&input, &state.camera, + speed, state.dt); + if (key_is_pressed(input.action_up)) + dv = v3f_scalef(dv, 3.0f); + camera_dp = v3f_add(camera_dp, dv); + camera_dp = v3f_scalef(camera_dp, 0.8f); + state.camera.pos = v3f_add(state.camera.pos, camera_dp); + + F32 sensitivity = 0.1f; + input.mouse_offset = v2f_scalef(input.mouse_offset, sensitivity); + state.camera.yaw += input.mouse_offset.x; + state.camera.pitch += input.mouse_offset.y; + if (state.camera.pitch > 89.0f) + state.camera.pitch = 89.0f; + if (state.camera.pitch < -89.0f) + state.camera.pitch = -89.0f; + + input_update_last_state(&input); + + angle += 40.0f*state.dt; + + x = f32_cos((F32)time); + y = f32_sin((F32)time); + z = 1.0f; + light_pos = v3f(x, y, z); + + /* NOTE(pryazha): Render */ + aspect = (F32)width/(F32)height; + proj = perspective(state.camera.fovx, aspect, + state.camera.near, state.camera.far); + view = get_view_matrix(&state.camera); + + glViewport(0, 0, width, height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glUseProgram(normal_map_shader); + shader_set_mat4fv(normal_map_shader, "proj", proj); + shader_set_mat4fv(normal_map_shader, "view", view); + shader_set_3fv(normal_map_shader, "light_pos", light_pos); + shader_set_3fv(normal_map_shader, "view_pos", state.camera.pos); + model = mat4_rotate_angles(mat4_identity(), v3f(angle, angle, angle)); + shader_set_mat4fv(normal_map_shader, "model", model); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, brickwall_diffuse_texture); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, brickwall_normal_texture); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glUseProgram(0); + + glUseProgram(color_shader); + shader_set_mat4fv(color_shader, "proj", proj); + shader_set_mat4fv(color_shader, "view", view); + model = mat4_make_scale(v3f(0.05f, 0.05f, 0.05f)); + model = mat4_translate(model, light_pos); + shader_set_mat4fv(color_shader, "model", model); + mesh_draw(cube); + glUseProgram(0); + + glUseProgram(normals_debug_shader); + shader_set_mat4fv(normals_debug_shader, "proj", proj); + shader_set_mat4fv(normals_debug_shader, "view", view); + model = mat4_rotate_angles(mat4_identity(), v3f(angle, angle, angle)); + shader_set_mat4fv(normals_debug_shader, "model", model); + glBindVertexArray(quad_vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glUseProgram(0); + + glfwSwapBuffers(window); + + time = glfwGetTime(); + state.dt = time-last_time; + last_time = time; + } + + arena_release(arena); + glfwTerminate(); + return(0); + +error: + arena_release(arena); + glfwTerminate(); + return(1); } |