This commit is contained in:
sam 2024-05-10 09:06:15 +12:00
commit 6264446526
5 changed files with 187 additions and 0 deletions

BIN
a.out Executable file

Binary file not shown.

BIN
libgearlib.a Normal file

Binary file not shown.

63
main.c Normal file
View file

@ -0,0 +1,63 @@
#include <gearlib.h>
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;
}

113
raycast.frag Normal file
View file

@ -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);
}

11
raycast.vert Normal file
View file

@ -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);
}