commit 6264446526646897dcac81d4497466128b567f25 Author: sam Date: Fri May 10 09:06:15 2024 +1200 a diff --git a/a.out b/a.out new file mode 100755 index 0000000..243e0de Binary files /dev/null and b/a.out differ diff --git a/libgearlib.a b/libgearlib.a new file mode 100644 index 0000000..7cb51b7 Binary files /dev/null and b/libgearlib.a differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..82def81 --- /dev/null +++ b/main.c @@ -0,0 +1,63 @@ +#include + +int main() { + Window window = create_window(800, 600, "raytracing"); + glfwSwapInterval(0); + enable_debugging(); + + RenderBatch* surface = create_batch(sizeof(vec2), 6); + surface->shader = load_shader_program( + compile_shader("raycast.vert", GL_VERTEX_SHADER), + compile_shader("raycast.frag", GL_FRAGMENT_SHADER), 0); + + batch_add_attrib(surface, (VertexAttrib){ + .type = GL_FLOAT, .size = sizeof(float), .count = 2 + }); + + batch_bind_attribs(surface); + + vec2 vertices[] = { + vec2(-1.0f, 1.0f), vec2(-1.0f, -1.0f), vec2(1.0f, -1.0f), + vec2(1.0f, -1.0f), vec2(1.0f, 1.0f), vec2(-1.0f, 1.0f), + }; + + glNamedBufferSubData(surface->vbo, 0, surface->vertex_size * 6, vertices); + glUseProgram(surface->shader); + + float start_time = glfwGetTime(); + float elapsed_time = 0.0f; + + uint32_t ssbo; + glCreateBuffers(1, &ssbo); + glNamedBufferStorage(ssbo, sizeof(int), NULL, GL_DYNAMIC_STORAGE_BIT); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo); + + int ray_count = 0; + + while(!glfwWindowShouldClose(window)) { + //glNamedBufferSubData(ssbo, 0, sizeof(int), &ray_count); + int w, h; + glfwGetWindowSize(window, &w, &h); + float aspect_ratio = (float)w / (float)h; + glUniform1f(0, aspect_ratio); + glUniform1f(1, sin(elapsed_time)); + + renderer_draw(surface->vao, 6); + + glfwSwapBuffers(window); + glfwPollEvents(); + + float end_time = glfwGetTime(); + float frame_time = end_time - start_time; + start_time = end_time; + + elapsed_time += frame_time; + + float fps = 1.0f / frame_time; + printf("fps: %f\n", fps); + } + + glfwDestroyWindow(window); + glfwTerminate(); + return 0; +} diff --git a/raycast.frag b/raycast.frag new file mode 100644 index 0000000..2aaccec --- /dev/null +++ b/raycast.frag @@ -0,0 +1,113 @@ +#version 460 core + +in vec2 pos; +out vec4 color; + +layout(location = 0) uniform float aspect_ratio; +layout(location = 1) uniform float sphere_y; + +layout(std430, binding = 0) buffer data +{ + int ray_count; +}; + +struct Ray { + vec3 origin; + vec3 direction; +}; + +struct Sphere { + vec3 center; + float radius; +}; + +vec3 unit_vector(vec3 v) { + return v / length(v); +} + +float length_squared(vec3 v) { + float length = length(v); + return length * length; +} + +float hit_sphere(Ray r, Sphere s) { + vec3 oc = s.center - r.origin; + float a = length_squared(r.direction); + float h = dot(r.direction, oc); + float c = length_squared(oc) - s.radius * s.radius; + float discriminant = h * h - a * c; + + if(discriminant > 0.0) { + return (h - sqrt(discriminant)) / a; + } + + return -1.0; +} + +vec3 at(Ray r, float time) { + return r.origin + time * r.direction; +} + +vec3 get_normal_color(Ray r, vec3 pos, Sphere s) { + vec3 normal = unit_vector(pos - s.center); + return 0.5 * vec3(normal + vec3(1.0, 1.0, 1.0)); +} + +Sphere spheres[] = { + Sphere(vec3(0, sphere_y, -1), 0.5), + Sphere(vec3(2, 0, 0), 0.25), + Sphere(vec3(0, -100.5, -1), 100.0) +}; + +struct HitInfo { + vec3 pos; + bool hit; + int index; +}; + +HitInfo hit_spheres(Ray r) { + float t_min = 0; + int index; + bool hit = false; + + for(int i = 0; i < spheres.length(); i++) { + Sphere s = spheres[i]; + float t = hit_sphere(r, s); + if(t > 0.0 && (!hit || t < t_min)) { + t_min = t; + index = i; + hit = true; + } + } + + return HitInfo(hit ? at(r, t_min) : vec3(0.0), hit, index); +} + +vec3 ray_color(Ray r) { + HitInfo info = hit_spheres(r); + if(info.hit) { + vec3 sun_dir = vec3(10, 10, 10) - info.pos; + Ray sun_ray = Ray(info.pos, sun_dir); + HitInfo sun_hit = hit_spheres(sun_ray); + + return get_normal_color(r, info.pos, + spheres[info.index]) - + (sun_hit.hit && sun_hit.index != info.index ? 0.4 : 0.0); + } + + vec3 unit_direction = unit_vector(r.direction); + float a = 0.5 * (unit_direction.y + 1.0); + return (1.0 - a) * vec3(1.0, 1.0, 1.0) + a * vec3(0.5, 0.7, 1.0); +} + +void main() { + vec3 p = vec3(pos, 0.0); + p.x *= aspect_ratio; + + vec3 camera_pos = vec3(0.0, 0.0, 0.0); + camera_pos.z += 1.0; + vec3 ray_dir = p - camera_pos; + + Ray r = Ray(camera_pos, ray_dir); + color = vec4(ray_color(r), 1.0); +} diff --git a/raycast.vert b/raycast.vert new file mode 100644 index 0000000..3f82eee --- /dev/null +++ b/raycast.vert @@ -0,0 +1,11 @@ +#version 460 core + +in vec2 a_pos; +out vec2 pos; +out vec2 uv; + +void main() { + pos = a_pos; + uv = (a_pos / 2.0) + 0.5; + gl_Position = vec4(a_pos, 0.0, 1.0); +}