This commit is contained in:
Lauchmelder 2022-10-20 23:46:15 +02:00
parent 5e61cd8c50
commit 196bdaf98b
10 changed files with 425 additions and 444 deletions

View file

@ -13,7 +13,7 @@ add_executable(solver
"renderer/buffer.c" "renderer/buffer.c"
"renderer/shader.c" "renderer/shader.c"
"renderer/camera.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 target_include_directories(solver PRIVATE
${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}

View file

@ -4,8 +4,7 @@
#include <errno.h> #include <errno.h>
#include "renderer/context.h" #include "renderer/context.h"
#include "objects/cube.h" #include "scenes/test_scene.h"
#include "scenes/spinning_cubes.h"
static void on_window_size_change(Application* app, int width, int height) 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->scenes = (Scene*)malloc(1 * sizeof(Scene));
app->active_scene = app->scenes; // First scene is active 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; return 1;
} }

227
src/objects/arrow.c Normal file
View file

@ -0,0 +1,227 @@
#include "arrow.h"
#include <stdio.h>
#include <glad/glad.h>
#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;
}
}

10
src/objects/arrow.h Normal file
View file

@ -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

View file

@ -1,147 +0,0 @@
#include "cube.h"
#include <stdio.h>
#include <glad/glad.h>
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;
}
}

View file

@ -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

View file

@ -6,8 +6,6 @@
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "objects/cube.h"
int create_scene(Scene* scene) int create_scene(Scene* scene)
{ {
assert(scene); assert(scene);

View file

@ -1,275 +0,0 @@
#include "spinning_cubes.h"
#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <GLFW/glfw3.h>
#include <cglm/affine.h>
#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;
}

184
src/scenes/test_scene.c Normal file
View file

@ -0,0 +1,184 @@
#include "test_scene.h"
#include <stdio.h>
#include <assert.h>
#include <stdbool.h>
#include <GLFW/glfw3.h>
#include <cglm/affine.h>
#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;
}

View file

@ -4,6 +4,6 @@
#include "scene.h" #include "scene.h"
#include "renderer/window.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 #endif // SCENE_SPINNING_CUBES_H