#include "GL/glew.h" #include "GLFW/glfw3.h" #include "pwyazh.h" #include "common.h" typedef struct { Arena *arena; Input input; Camera camera; Mesh *cube; GLFWwindow *window; } state_t; static S32 width = 1600; static S32 height = 800; void die(const char *fmt, ...) { fprintf(stderr, "error: "); va_list args; va_start(args, fmt); vprintf(fmt, args); va_end(args); fprintf(stderr, "\n"); exit(1); } void init_glfw(state_t *state) { glfwSetErrorCallback(error_callback); if (glfwInit() == GLFW_FALSE) die("failed to initialize glfw"); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); state->window = glfwCreateWindow(width, height, "prb lighting", 0, 0); if (!state->window) die("failed to create window"); glfwSetInputMode(state->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwMakeContextCurrent(state->window); } void init_gl(void) { if (glewInit() != GLEW_OK) die("failed to initialize glew"); glEnable(GL_DEPTH_TEST); } state_t init_state(void) { state_t state = { .arena = arena_alloc(Kilobytes(256)), .input = input_init(), .camera = { .pos = v3f(0.0f, 2.0f, 5.0f), .fovx = 90.0f, .near = 0.1f, .far = 100.0f, .yaw = 0.0f, .pitch = 0.0f }, }; return state; } int main(void) { state_t state = init_state(); init_glfw(&state); init_gl(); // meshes Mesh *cube = mesh_load_obj(state.arena, "../../data/models/cube.obj"); // shaders U32 shader = load_shader("default.vert", "default.frag"); F64 last_time = glfwGetTime(); while (!glfwWindowShouldClose(state.window)) { F64 time = glfwGetTime(); F32 dt = time - last_time; last_time = time; input_update_last_state(&state.input); glfwPollEvents(); process_glfw_keyboard(state.window, &state.input); process_glfw_mouse_pos(state.window, &state.input); if (key_first_press(state.input.exit)) glfwSetWindowShouldClose(state.window, GLFW_TRUE); F32 speed = 2.0f; V3F dv = get_dv_camera_first_person(&state.input, &state.camera, speed, dt); V3F 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; state.input.mouse_offset = v2f_scalef(state.input.mouse_offset, sensitivity); state.camera.yaw += state.input.mouse_offset.x; state.camera.pitch += state.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; // update // render F32 ar = (F32)width / (F32)height; MAT4 projection = camera_persp(state.camera, ar); MAT4 view = get_view_matrix(&state.camera); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(shader); mesh_draw(cube); glUseProgram(0); glfwSwapBuffers(state.window); } return 0; }