diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 078a000..21da263 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,7 @@ add_executable(solver "renderer/buffer.c" "renderer/shader.c" "renderer/camera.c" - "objects/cube.c" "renderer/object.c" "util/dynarray.h" "util/dynarray.c" "scenes/spinning_cubes.h" "scenes/spinning_cubes.c" "renderer/light/point_light.h" "renderer/light/ambient_light.h") + "renderer/object.c" "util/dynarray.h" "util/dynarray.c" "scenes/test_scene.h" "scenes/test_scene.c" "renderer/light/point_light.h" "renderer/light/ambient_light.h" "objects/arrow.h" "objects/arrow.c") target_include_directories(solver PRIVATE ${CMAKE_CURRENT_LIST_DIR} diff --git a/src/application.c b/src/application.c index a923807..8367a84 100644 --- a/src/application.c +++ b/src/application.c @@ -4,8 +4,7 @@ #include #include "renderer/context.h" -#include "objects/cube.h" -#include "scenes/spinning_cubes.h" +#include "scenes/test_scene.h" static void on_window_size_change(Application* app, int width, int height) { @@ -36,7 +35,7 @@ int init_application(Application* app, const char* name) app->scenes = (Scene*)malloc(1 * sizeof(Scene)); app->active_scene = app->scenes; // First scene is active scene - if (create_spinning_cubes_scene(&app->window, app->scenes) != 0) + if (create_test_scene(&app->window, app->scenes) != 0) { return 1; } diff --git a/src/objects/arrow.c b/src/objects/arrow.c new file mode 100644 index 0000000..fc13203 --- /dev/null +++ b/src/objects/arrow.c @@ -0,0 +1,227 @@ +#include "arrow.h" + +#include +#include + +#include "renderer/object.h" + +static VertexArrayObject* vao = NULL; +static size_t num_arrows = 0; + +static vec3 arrow_color = { 0.5f, 0.5f, 0.5f }; + +static int init_cube_object(void) +{ + vao = (VertexArrayObject*)malloc(sizeof(VertexArrayObject)); + if (vao == NULL) + { + fprintf(stderr, "Failed to allocate memory for cube vao\n"); + return 1; + } + + create_vao(vao); + float cube_vertices[] = { + -30.0, 0.0, 1.0, 0.0, 2.93, 7.07, + 30.0, 0.0, 1.0, 0.0, 2.93, 7.07, + 30.0, 0.707, 0.707, 0.0, 2.93, 7.07, + -30.0, 0.0, 1.0, 0.0, 2.93, 7.07, + 30.0, 0.707, 0.707, 0.0, 2.93, 7.07, + -30.0, 0.707, 0.707, 0.0, 2.93, 7.07, + + -30.0, 0.707, 0.707, 0.0, 7.07, 2.93, + 30.0, 0.707, 0.707, 0.0, 7.07, 2.93, + 30.0, 1.0, 0.0, 0.0, 7.07, 2.93, + -30.0, 0.707, 0.707, 0.0, 7.07, 2.93, + 30.0, 1.0, 0.0, 0.0, 7.07, 2.93, + -30.0, 1.0, 0.0, 0.0, 7.07, 2.93, + + -30.0, 1.0, 0.0, 0.0, 7.07, -2.93, + 30.0, 1.0, 0.0, 0.0, 7.07, -2.93, + 30.0, 0.707, -0.707, 0.0, 7.07, -2.93, + -30.0, 1.0, 0.0, 0.0, 7.07, -2.93, + 30.0, 0.707, -0.707, 0.0, 7.07, -2.93, + -30.0, 0.707, -0.707, 0.0, 7.07, -2.93, + + -30.0, 0.707, -0.707, 0.0, 2.93, -7.07, + 30.0, 0.707, -0.707, 0.0, 2.93, -7.07, + 30.0, 0.0, -1.0, 0.0, 2.93, -7.07, + -30.0, 0.707, -0.707, 0.0, 2.93, -7.07, + 30.0, 0.0, -1.0, 0.0, 2.93, -7.07, + -30.0, 0.0, -1.0, 0.0, 2.93, -7.07, + + -30.0, -0.0, 1.0, 0.0, -2.93, 7.07, + 30.0, -0.0, 1.0, 0.0, -2.93, 7.07, + 30.0, -0.707, 0.707, 0.0, -2.93, 7.07, + -30.0, -0.0, 1.0, 0.0, -2.93, 7.07, + 30.0, -0.707, 0.707, 0.0, -2.93, 7.07, + -30.0, -0.707, 0.707, 0.0, -2.93, 7.07, + + -30.0, -0.707, 0.707, 0.0, -7.07, 2.93, + 30.0, -0.707, 0.707, 0.0, -7.07, 2.93, + 30.0, -1.0, 0.0, 0.0, -7.07, 2.93, + -30.0, -0.707, 0.707, 0.0, -7.07, 2.93, + 30.0, -1.0, 0.0, 0.0, -7.07, 2.93, + -30.0, -1.0, 0.0, 0.0, -7.07, 2.93, + + -30.0, -1.0, 0.0, 0.0, -7.07, -2.93, + 30.0, -1.0, 0.0, 0.0, -7.07, -2.93, + 30.0, -0.707, -0.707, 0.0, -7.07, -2.93, + -30.0, -1.0, 0.0, 0.0, -7.07, -2.93, + 30.0, -0.707, -0.707, 0.0, -7.07, -2.93, + -30.0, -0.707, -0.707, 0.0, -7.07, -2.93, + + -30.0, -0.707, -0.707, 0.0, -2.93, -7.07, + 30.0, -0.707, -0.707, 0.0, -2.93, -7.07, + 30.0, -0.0, -1.0, 0.0, -2.93, -7.07, + -30.0, -0.707, -0.707, 0.0, -2.93, -7.07, + 30.0, -0.0, -1.0, 0.0, -2.93, -7.07, + -30.0, -0.0, -1.0, 0.0, -2.93, -7.07, + + -30.0, 0.0, 1.0, -1.0, 0.0, 0.0, + -30.0, 0.707, 0.707, -1.0, 0.0, 0.0, + -30.0, -0.707, 0.707, -1.0, 0.0, 0.0, + -30.0, 1.0, 0.0, -1.0, 0.0, 0.0, + -30.0, 0.707, 0.707, -1.0, 0.0, 0.0, + -30.0, -0.707, 0.707, -1.0, 0.0, 0.0, + -30.0, 1.0, 0.0, -1.0, 0.0, 0.0, + -30.0, -0.707, 0.707, -1.0, 0.0, 0.0, + -30.0, -1.0, 0.0, -1.0, 0.0, 0.0, + -30.0, 0.0, -1.0, -1.0, 0.0, 0.0, + -30.0, 0.707, -0.707, -1.0, 0.0, 0.0, + -30.0, -0.707, -0.707, -1.0, 0.0, 0.0, + -30.0, 1.0, -0.0, -1.0, 0.0, 0.0, + -30.0, 0.707, -0.707, -1.0, 0.0, 0.0, + -30.0, -0.707, -0.707, -1.0, 0.0, 0.0, + -30.0, 1.0, -0.0, -1.0, 0.0, 0.0, + -30.0, -0.707, -0.707, -1.0, 0.0, 0.0, + -30.0, -1.0, -0.0, -1.0, 0.0, 0.0, + + 30.0, 0.0, 1.5, -1.0, 0.0, 0.0, + 30.0, 1.0605, 1.0605, -1.0, 0.0, 0.0, + 30.0, -1.0605, 1.0605, -1.0, 0.0, 0.0, + 30.0, 1.5, 0.0, -1.0, 0.0, 0.0, + 30.0, 1.0605, 1.0605, -1.0, 0.0, 0.0, + 30.0, -1.0605, 1.0605, -1.0, 0.0, 0.0, + 30.0, 1.5, 0.0, -1.0, 0.0, 0.0, + 30.0, -1.0605, 1.0605, -1.0, 0.0, 0.0, + 30.0, -1.5, 0.0, -1.0, 0.0, 0.0, + 30.0, 0.0, -1.5, -1.0, 0.0, 0.0, + 30.0, 1.0605, -1.0605, -1.0, 0.0, 0.0, + 30.0, -1.0605, -1.0605, -1.0, 0.0, 0.0, + 30.0, 1.5, -0.0, -1.0, 0.0, 0.0, + 30.0, 1.0605, -1.0605, -1.0, 0.0, 0.0, + 30.0, -1.0605, -1.0605, -1.0, 0.0, 0.0, + 30.0, 1.5, -0.0, -1.0, 0.0, 0.0, + 30.0, -1.0605, -1.0605, -1.0, 0.0, 0.0, + 30.0, -1.5, -0.0, -1.0, 0.0, 0.0, + + 30.0, 0.0, 1.5, 1.59075, 1.3185, 3.1815, + 30.0, 1.0605, 1.0605, 1.59075, 1.3185, 3.1815, + 33.0, 0.0, 0.0, 1.59075, 1.3185, 3.1815, + 30.0, 1.0605, 1.0605, 1.59075, 3.1815, 1.3185, + 30.0, 1.5, 0.0, 1.59075, 3.1815, 1.3185, + 33.0, 0.0, 0.0, 1.59075, 3.1815, 1.3185, + 30.0, 1.5, 0.0, 1.59075, 3.1815, -1.3185, + 30.0, 1.0605, -1.0605, 1.59075, 3.1815, -1.3185, + 33.0, 0.0, 0.0, 1.59075, 3.1815, -1.3185, + 30.0, 1.0605, -1.0605, 1.59075, 1.3185, -3.1815, + 30.0, 0.0, -1.5, 1.59075, 1.3185, -3.1815, + 33.0, 0.0, 0.0, 1.59075, 1.3185, -3.1815, + 30.0, -0.0, 1.5, 1.59075, -1.3185, 3.1815, + 30.0, -1.0605, 1.0605, 1.59075, -1.3185, 3.1815, + 33.0, -0.0, 0.0, 1.59075, -1.3185, 3.1815, + 30.0, -1.0605, 1.0605, 1.59075, -3.1815, 1.3185, + 30.0, -1.5, 0.0, 1.59075, -3.1815, 1.3185, + 33.0, -0.0, 0.0, 1.59075, -3.1815, 1.3185, + 30.0, -1.5, 0.0, 1.59075, -3.1815, -1.3185, + 30.0, -1.0605, -1.0605, 1.59075, -3.1815, -1.3185, + 33.0, -0.0, 0.0, 1.59075, -3.1815, -1.3185, + 30.0, -1.0605, -1.0605, 1.59075, -1.3185, -3.1815, + 30.0, -0.0, -1.5, 1.59075, -1.3185, -3.1815, + 33.0, -0.0, 0.0, 1.59075, -1.3185, -3.1815, + + }; + attach_vertex_buffer(vao, cube_vertices, sizeof(cube_vertices)); + + unsigned cube_indices[] = { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, + 48, 49, 50, + 51, 52, 53, + 54, 55, 56, + 57, 58, 59, + 60, 61, 62, + 63, 64, 65, + 66, 67, 68, + 69, 70, 71, + 72, 73, 74, + 75, 76, 77, + 78, 79, 80, + 81, 82, 83, + 84, 85, 86, + 87, 88, 89, + 90, 91, 92, + 93, 94, 95, + 96, 97, 98, + 99, 100, 101, + 102, 103, 104, + 105, 106, 107 + }; + attach_element_buffer(vao, cube_indices, sizeof(cube_indices)); + + VertexAttribute attributes[] = { + { GL_FLOAT, 3, sizeof(float) }, + { GL_FLOAT, 3, sizeof(float) } + }; + set_vertex_layout(vao, attributes, sizeof(attributes) / sizeof(VertexAttribute)); + + return 0; +} + +static void on_shader_bind(Arrow* cube, Shader* shader) +{ + set_uniform_vec3(shader, "object_color", arrow_color); +} + +static void on_update(Arrow* cube) +{ + +} + +int create_arrow(Arrow* arrow) +{ + if (vao == NULL) + { + if (init_cube_object() != 0) + { + return 1; + } + } + + init_object(arrow); + arrow->vao = vao; + + arrow->child = arrow; + arrow->on_shader_use_obj = on_shader_bind; + arrow->on_update = on_update; + arrow->on_destroy = destroy_arrow; + + num_arrows++; +} + +void destroy_arrow(Arrow* arrow) +{ + num_arrows--; + + if (num_arrows == 0) + { + destroy_vao(*vao); + vao = NULL; + } +} \ No newline at end of file diff --git a/src/objects/arrow.h b/src/objects/arrow.h new file mode 100644 index 0000000..1c4338d --- /dev/null +++ b/src/objects/arrow.h @@ -0,0 +1,10 @@ +#ifndef OBJECT_ARROW_H +#define OBJECT_ARROW_H + +typedef struct Object Object; +typedef Object Arrow; + +int create_arrow(Arrow* arrow); +void destroy_arrow(Arrow* arrow); + +#endif \ No newline at end of file diff --git a/src/objects/cube.c b/src/objects/cube.c deleted file mode 100644 index a141531..0000000 --- a/src/objects/cube.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "cube.h" - -#include -#include - -static VertexArrayObject* vao = NULL; -static size_t num_cubes = 0; - -static int init_cube_object(void) -{ - vao = (VertexArrayObject*) malloc(sizeof(VertexArrayObject)); - if (vao == NULL) - { - fprintf(stderr, "Failed to allocate memory for cube vao\n"); - return 1; - } - - create_vao(vao); - float cube_vertices[] = { - -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, - - -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, - - -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, - -1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, - -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, - -1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, - -1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, - -1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, - - 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, - - -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, - 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, - 1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, - -1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, - -1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, - - -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, - 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f - }; - attach_vertex_buffer(vao, cube_vertices, sizeof(cube_vertices)); - - unsigned cube_indices[] = { - 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35 - }; - attach_element_buffer(vao, cube_indices, sizeof(cube_indices)); - - VertexAttribute attributes[] = { - { GL_FLOAT, 3, sizeof(float) }, - { GL_FLOAT, 3, sizeof(float) } - }; - set_vertex_layout(vao, attributes, sizeof(attributes) / sizeof(VertexAttribute)); - - return 0; -} - -static void on_shader_bind(Cube* cube, Shader* shader) -{ - set_uniform_vec3(shader, "cube_color", cube->color); -} - -static void on_update(Cube* cube) -{ - cube->object.rotation[1] += 0.05f; - - for (int i = 0; i < 3; i++) - { - cube->color[i] += cube->color_mod[i]; - - if (cube->color[i] > 1.0f) - { - cube->color_mod[i] *= -1.0f; - cube->color[i] = 1.0f; - } - else if (cube->color[i] < 0.0f) - { - cube->color_mod[i] *= -1.0f; - cube->color[i] = 0.0f; - } - } -} - -int create_cube(Cube* cube) -{ - if (vao == NULL) - { - if (init_cube_object() != 0) - { - return 1; - } - } - - init_object(&cube->object); - glm_vec3_one(cube->color); - - cube->color_mod[0] = 0.01f; - cube->color_mod[1] = 0.006f; - cube->color_mod[2] = 0.005f; - - cube->object.vao = vao; - - cube->object.child = cube; - cube->object.on_shader_use_obj = on_shader_bind; - cube->object.on_update = on_update; - cube->object.on_destroy = destroy_cube; - - num_cubes++; -} - -void destroy_cube(Cube* cube) -{ - num_cubes--; - - if (num_cubes == 0) - { - destroy_vao(*vao); - vao = NULL; - } -} - - diff --git a/src/objects/cube.h b/src/objects/cube.h deleted file mode 100644 index d913566..0000000 --- a/src/objects/cube.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef OBJ_CUBE_H -#define OBJ_CUBE_H - -#include "renderer/object.h" - -typedef struct Cube { - Object object; - vec3 color; - vec3 color_mod; -} Cube; - -int create_cube(Cube* cube); -void destroy_cube(Cube* cube); - -#endif // OBJ_CUBE_H \ No newline at end of file diff --git a/src/scene.c b/src/scene.c index f405141..7f5496f 100644 --- a/src/scene.c +++ b/src/scene.c @@ -6,8 +6,6 @@ #include #include -#include "objects/cube.h" - int create_scene(Scene* scene) { assert(scene); diff --git a/src/scenes/spinning_cubes.c b/src/scenes/spinning_cubes.c deleted file mode 100644 index 6b90769..0000000 --- a/src/scenes/spinning_cubes.c +++ /dev/null @@ -1,275 +0,0 @@ -#include "spinning_cubes.h" - -#include -#include -#include - -#include -#include - -#include "objects/cube.h" -#include "application.h" -#include "renderer/object.h" - -static const char* vertex_shader = -"#version 460 core\n" -"" -"layout (location = 0) in vec3 pos;" -"layout (location = 1) in vec3 normal;" -"" -"out vec3 frag_normal;" -"out vec3 frag_pos;" -"" -"uniform mat4 model;" -"uniform mat4 view;" -"uniform mat4 projection;" -"" -"void main() {" -" frag_normal = mat3(transpose(inverse(model))) * normal;" -" frag_pos = vec3(model * vec4(pos, 1.0));" -" gl_Position = projection * view * model * vec4(pos, 1.0);" -"}"; - -static const char* fragment_shader = -"#version 460 core\n" -"" -"in vec3 frag_pos;" -"in vec3 frag_normal;" -"" -"uniform vec3 ambient_color = vec3(1.0, 1.0, 1.0);" -"uniform float ambient_intens = 1.0f;" -"" -"uniform vec3 point_pos = vec3(0.0, 0.0, 0.0);" -"uniform vec3 point_col = vec3(1.0, 1.0, 1.0);" -"uniform float point_intens = 1.0f;" -"" -"uniform vec3 cam_pos = vec3(0.0, 0.0, 0.0);" -"float specular_strength = 0.5f;" -"" -"uniform vec3 cube_color;" -"" -"out vec4 FragColor;" -"" -"void main() {" -" vec3 ambient = ambient_intens * ambient_color;" -"" -" vec3 norm = normalize(frag_normal);" -" vec3 light_dir = normalize(point_pos - frag_pos);" -" float diff = max(dot(norm, light_dir), 0.0);" -" vec3 diffuse = diff * point_col;" -"" -" vec3 view_dir = normalize(cam_pos - frag_pos);" -" vec3 reflect_dir = reflect(-light_dir, norm);" -"" -" float spec = pow(max(dot(view_dir, reflect_dir), 0.0), 32);" -" vec3 specular = specular_strength * spec * point_col; " -"" -" vec3 result = (ambient + diffuse + specular) * cube_color;" -" FragColor = vec4(result, 1.0);" -"}"; - -typedef struct SpinningCubes -{ - Shader cube_shader; - DynamicArray objects; - - AmbientLight ambient_light; - PointLight point_light; - - struct { - double x, y; - } last_cursor_pos; - - bool dragging; - double drag_speed; - double camera_distance; - - double time; -} SpinningCubes; - -static void set_lighting_uniforms(Shader* shader, Scene* scene) -{ - SpinningCubes* data = scene->child; - - set_uniform_vec3(shader, "ambient_color", data->ambient_light.color); - set_uniform_float(shader, "ambient_intens", data->ambient_light.intensity); - - set_uniform_vec3(shader, "point_pos", data->point_light.position); - set_uniform_vec3(shader, "point_col", data->point_light.color); - set_uniform_float(shader, "point_intens", data->point_light.intensity); - - set_uniform_vec3(shader, "cam_pos", scene->camera.object.position); -} - -static void init_spinning_cubes_data(SpinningCubes* scene) -{ - assert(scene); - - scene->camera_distance = 6.5f; - scene->dragging = false; - scene->drag_speed = 0.01f; - scene->time = 0.0f; - - scene->objects = create_dynamic_array(Object*); -} - -static void get_arcball_vector(vec3 dest, double width, double height, double x, double y) -{ - dest[0] = 1.0 * x / width * 2 - 1.0; - dest[1] = 1.0 * y / height * 2 - 1.0; - dest[2] = 0.0; - - dest[2] = -dest[2]; - float OP_squared = dest[0] * dest[0] + dest[1] * dest[1]; - if (OP_squared <= 1) - dest[2] = sqrt(1 - OP_squared); - else - glm_normalize(dest); -} - -static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) -{ - Application* app = glfwGetWindowUserPointer(window); - Scene* scene = app->active_scene; - SpinningCubes* data = scene->child; - - switch (button) - { - case GLFW_MOUSE_BUTTON_LEFT: - { - if (action == GLFW_PRESS) - { - data->dragging = true; - - glfwGetCursorPos(window, &data->last_cursor_pos.x, &data->last_cursor_pos.y); - } - else if (action == GLFW_RELEASE) - { - data->dragging = false; - } - } break; - - default: - break; - } -} - -static void mouse_moved_callback(GLFWwindow* window, double xpos, double ypos) -{ - return; - - Application* app = glfwGetWindowUserPointer(window); - Scene* scene = app->active_scene; - SpinningCubes* data = scene->child; - - if (data->dragging && (xpos != data->last_cursor_pos.x || ypos != data->last_cursor_pos.y)) - { - Object* camera = &scene->camera.object; - int width, height; - glfwGetWindowSize(window, &width, &height); - - vec3 va; get_arcball_vector(va, width, height, data->last_cursor_pos.x, data->last_cursor_pos.y); - vec3 vb; get_arcball_vector(vb, width, height, xpos, ypos); - - vec3 diff; glm_vec3_sub(vb, va, diff); - - object_move(camera, diff); - vec3 look_dir; glm_vec3_sub(scene->camera.look_at, camera->position, look_dir); - double cam_distance = glm_vec3_norm(look_dir); - if (cam_distance != data->camera_distance) - { - double correction = data->camera_distance - cam_distance; - glm_normalize(look_dir); - glm_vec3_scale(look_dir, correction, look_dir); - - object_move(camera, look_dir); - } - - data->last_cursor_pos.x = xpos; - data->last_cursor_pos.y = ypos; - } -} - -static void on_update(Scene* scene, double frametime) -{ - SpinningCubes* data = scene->child; - - for (int i = 0; i < data->objects.size; i++) - { - Object* obj = *(Object**)dynamic_array_get(&data->objects, i); - update_object(obj); - } - - vec3 cam_pos = { 6.0f * sin(2.0f * data->time), 3.5f * cos(data->time), 6.0f * cos(2.0f * data->time)}; - - object_set_position(&scene->camera.object, cam_pos); - data->time += frametime; - - glm_vec3_copy(scene->camera.object.position, data->point_light.position); -} - -static void on_render(Scene* scene) -{ - SpinningCubes* data = scene->child; - - bind_shader(&data->cube_shader); - set_lighting_uniforms(&data->cube_shader, scene); - scene_set_camera_uniforms(scene, &data->cube_shader); - - for (int i = 0; i < data->objects.size; i++) - { - shader_add_object(&data->cube_shader, *(Object**)dynamic_array_get(&data->objects, i)); - } - - shader_render(&data->cube_shader); -} - -int create_spinning_cubes_scene(Window* window, Scene* scene) -{ - assert(scene); - - create_scene(scene); - scene->on_update = on_update; - scene->on_render = on_render; - scene->child = malloc(sizeof(SpinningCubes)); - init_spinning_cubes_data(scene->child); - - SpinningCubes* data = scene->child; - for (int i = 0; i < 4; i++) - { - Cube* obj = (Cube*)malloc(sizeof(Cube)); - create_cube(obj); - - vec3 position = { - ((i % 2) ? -1 : 1) * 1.5f, - 0.0f, - ((i < 2) ? -1 : 1) * 1.5 - }; - - object_set_position(&obj->object, position); - - Object* raw_obj = &obj->object; - dynamic_array_push(&data->objects, (void*)&raw_obj); - } - - if(create_shader(&data->cube_shader, vertex_shader, fragment_shader) != 0) - { - fprintf(stderr, "failed to create shader for cube\n"); - return 1; - } - - vec3 cam_pos = { 0.0f, 3.5f, 3.0 }; - object_set_position(&scene->camera.object, cam_pos); - glm_vec3_zero(&scene->camera.look_at); - - glm_vec3_one(data->ambient_light.color); - data->ambient_light.intensity = 0.1f; - - glm_vec3_one(data->point_light.color); - data->point_light.intensity = 1.0f; - - glfwSetMouseButtonCallback(window->window, mouse_button_callback); - glfwSetCursorPosCallback(window->window, mouse_moved_callback); - - return 0; -} diff --git a/src/scenes/test_scene.c b/src/scenes/test_scene.c new file mode 100644 index 0000000..cd08253 --- /dev/null +++ b/src/scenes/test_scene.c @@ -0,0 +1,184 @@ +#include "test_scene.h" + +#include +#include +#include + +#include +#include + +#include "objects/arrow.h" +#include "application.h" +#include "renderer/object.h" + +static const char* vertex_shader = +"#version 460 core\n" +"" +"layout (location = 0) in vec3 pos;" +"layout (location = 1) in vec3 normal;" +"" +"out vec3 frag_normal;" +"out vec3 frag_pos;" +"" +"uniform mat4 model;" +"uniform mat4 view;" +"uniform mat4 projection;" +"" +"void main() {" +" frag_normal = mat3(transpose(inverse(model))) * normal;" +" frag_pos = vec3(model * vec4(pos, 1.0));" +" gl_Position = projection * view * model * vec4(pos, 1.0);" +"}"; + +static const char* fragment_shader = +"#version 460 core\n" +"" +"in vec3 frag_pos;" +"in vec3 frag_normal;" +"" +"uniform vec3 ambient_color = vec3(1.0, 1.0, 1.0);" +"uniform float ambient_intens = 1.0f;" +"" +"uniform vec3 point_pos = vec3(0.0, 0.0, 0.0);" +"uniform vec3 point_col = vec3(1.0, 1.0, 1.0);" +"uniform float point_intens = 1.0f;" +"" +"uniform vec3 cam_pos = vec3(0.0, 0.0, 0.0);" +"float specular_strength = 0.5f;" +"" +"uniform vec3 object_color;" +"" +"out vec4 FragColor;" +"" +"void main() {" +" vec3 ambient = ambient_intens * ambient_color;" +"" +" vec3 norm = normalize(frag_normal);" +" vec3 light_dir = normalize(point_pos - frag_pos);" +" float diff = max(dot(norm, light_dir), 0.0);" +" vec3 diffuse = diff * point_col;" +"" +" vec3 view_dir = normalize(cam_pos - frag_pos);" +" vec3 reflect_dir = reflect(-light_dir, norm);" +"" +" float spec = pow(max(dot(view_dir, reflect_dir), 0.0), 32);" +" vec3 specular = specular_strength * spec * point_col; " +"" +" vec3 result = (ambient + diffuse + specular) * object_color;" +" FragColor = vec4(result, 1.0);" +"}"; + +typedef struct SceneData +{ + Shader default_shader; + DynamicArray default_objects; + + AmbientLight ambient_light; + PointLight point_light; + + double time; +} SceneData; + +static void set_lighting_uniforms(Shader* shader, Scene* scene) +{ + SceneData* data = scene->child; + + set_uniform_vec3(shader, "ambient_color", data->ambient_light.color); + set_uniform_float(shader, "ambient_intens", data->ambient_light.intensity); + + set_uniform_vec3(shader, "point_pos", data->point_light.position); + set_uniform_vec3(shader, "point_col", data->point_light.color); + set_uniform_float(shader, "point_intens", data->point_light.intensity); + + set_uniform_vec3(shader, "cam_pos", scene->camera.object.position); +} + +static void init_spinning_cubes_data(SceneData* scene) +{ + assert(scene); + + scene->default_objects = create_dynamic_array(Object*); + scene->time = 0; +} + +static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) +{ + +} + +static void mouse_moved_callback(GLFWwindow* window, double xpos, double ypos) +{ + +} + +static void on_update(Scene* scene, double frametime) +{ + SceneData* data = scene->child; + + for (int i = 0; i < data->default_objects.size; i++) + { + Object* obj = *(Object**)dynamic_array_get(&data->default_objects, i); + update_object(obj); + } + + vec3 cam_pos = { 50.0f * sin(2.0f * data->time), 10.0f * cos(data->time), 50.0f * cos(2.0f * data->time)}; + + object_set_position(&scene->camera.object, cam_pos); + data->time += frametime; + + glm_vec3_copy(scene->camera.object.position, data->point_light.position); +} + +static void on_render(Scene* scene) +{ + SceneData* data = scene->child; + + bind_shader(&data->default_shader); + set_lighting_uniforms(&data->default_shader, scene); + scene_set_camera_uniforms(scene, &data->default_shader); + + for (int i = 0; i < data->default_objects.size; i++) + { + shader_add_object(&data->default_shader, *(Object**)dynamic_array_get(&data->default_objects, i)); + } + + shader_render(&data->default_shader); +} + +int create_test_scene(Window* window, Scene* scene) +{ + assert(scene); + + create_scene(scene); + scene->on_update = on_update; + scene->on_render = on_render; + scene->child = malloc(sizeof(SceneData)); + init_spinning_cubes_data(scene->child); + + SceneData* data = scene->child; + + Arrow* arrow = (Arrow*)malloc(sizeof(Arrow)); + create_arrow(arrow); + dynamic_array_push(&data->default_objects, (void*)&arrow); + + if(create_shader(&data->default_shader, vertex_shader, fragment_shader) != 0) + { + fprintf(stderr, "failed to create shader for cube\n"); + return 1; + } + + vec3 cam_pos = { 0.0f, 3.5f, 3.0 }; + object_set_position(&scene->camera.object, cam_pos); + glm_vec3_zero(&scene->camera.look_at); + + glm_vec3_one(data->ambient_light.color); + data->ambient_light.intensity = 0.1f; + + glm_vec3_one(data->point_light.color); + data->point_light.intensity = 1.0f; + + glfwSetMouseButtonCallback(window->window, mouse_button_callback); + glfwSetCursorPosCallback(window->window, mouse_moved_callback); + + return 0; +} diff --git a/src/scenes/spinning_cubes.h b/src/scenes/test_scene.h similarity index 69% rename from src/scenes/spinning_cubes.h rename to src/scenes/test_scene.h index 646db46..5046487 100644 --- a/src/scenes/spinning_cubes.h +++ b/src/scenes/test_scene.h @@ -4,6 +4,6 @@ #include "scene.h" #include "renderer/window.h" -int create_spinning_cubes_scene(Window* window, Scene* scene); +int create_test_scene(Window* window, Scene* scene); #endif // SCENE_SPINNING_CUBES_H \ No newline at end of file