diff options
Diffstat (limited to 'pbr/1.1.lighting/lighting.c')
-rw-r--r-- | pbr/1.1.lighting/lighting.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/pbr/1.1.lighting/lighting.c b/pbr/1.1.lighting/lighting.c new file mode 100644 index 0000000..87621ba --- /dev/null +++ b/pbr/1.1.lighting/lighting.c @@ -0,0 +1,128 @@ +#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; +} |