diff --git a/l_system_3d.c b/l_system_3d.c index 30da021..e9893f8 100644 --- a/l_system_3d.c +++ b/l_system_3d.c @@ -16,7 +16,7 @@ #define DEFAULT_WINDOW_WIDTH (800) #define DEFAULT_WINDOW_HEIGHT (600) #define DEFAULT_FPS (60.0) -#define DEFAULT_GEOMETRY_THICKNESS (0.5) +#define DEFAULT_GEOMETRY_THICKNESS (0.125) static ApplicationState* AllocateApplicationState(void) { ApplicationState *to_return = NULL; @@ -325,9 +325,8 @@ static int WaitNextFrame(ApplicationState *s) { static int RunMainLoop(ApplicationState *s) { glEnable(GL_DEPTH_TEST); - // TODO: Re-enable face culling after getting the geometry shader working. - //glEnable(GL_CULL_FACE); - //glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); glClearColor(0, 0, 0, 1.0); while (!glfwWindowShouldClose(s->window)) { s->frame_start = glfwGetTime(); diff --git a/pipes_shader.geom b/pipes_shader.geom index fc38534..1a6ae0c 100644 --- a/pipes_shader.geom +++ b/pipes_shader.geom @@ -1,6 +1,6 @@ #version 330 core layout (lines) in; -layout (line_strip, max_vertices = 4) out; +layout (triangle_strip, max_vertices = 3) out; in VS_OUT { vec3 position; @@ -28,35 +28,44 @@ float timeOffset() { return (sin(shared_uniforms.current_time * 3) + 1.0) * 0.5; } +// Takes a forward-facing vector and returns a vector that points to its right, +// along the camera plane. +vec3 cameraRight(vec3 position, vec3 forward) { + vec3 to_camera = shared_uniforms.camera_position.xyz - position; + return normalize(cross(forward, to_camera)); +} + void main() { - gs_out.forward = normal * gs_in[0].forward; - gs_out.up = normal * gs_in[0].up; - gs_out.right = normal * gs_in[0].right; + gs_out.forward = normalize(normal * gs_in[0].forward); + gs_out.up = normalize(normal * gs_in[0].up); + gs_out.right = normalize(normal * gs_in[0].right); gs_out.color = gs_in[1].color; mat4 projView = shared_uniforms.projection * shared_uniforms.view; vec4 pos_tmp = model * vec4(gs_in[0].position, 1); - pos_tmp += normalize(vec4(gs_out.forward, 1.0)) * timeOffset(); - gs_out.frag_position = pos_tmp.xyz; + vec3 frag_pos_start = pos_tmp.xyz; + gs_out.frag_position = frag_pos_start;; gl_Position = projView * pos_tmp; EmitVertex(); pos_tmp = model * vec4(gs_in[1].position, 1); - pos_tmp += normalize(vec4(gs_out.forward, 1.0)) * timeOffset(); - gs_out.frag_position = pos_tmp.xyz; + vec3 frag_pos_end = pos_tmp.xyz; + gs_out.frag_position = frag_pos_end; gl_Position = projView * pos_tmp; EmitVertex(); - EndPrimitive(); - // Add a second primitive: a line starting at each midpoint and pointing in - // the "up" direction. + // TODO (next): Continue the same thing, except put points to the left and + // right of both endpoints rather than a single triangle point to the left of + // the midpoint. + + // The third vertex is in the "up" direction from the midpoint of the + // original segment. vec3 dir = gs_in[1].position - gs_in[0].position; vec3 midpoint = gs_in[0].position + dir * 0.5; - pos_tmp = model * vec4(midpoint, 1.0); - gs_out.frag_position = pos_tmp.xyz; - gl_Position = projView * pos_tmp; - EmitVertex(); - pos_tmp = model * vec4(midpoint + gs_out.up * (length(dir) * 0.5), 1); + pos_tmp = model * vec4(midpoint, 1); + vec3 plane_right = cameraRight(pos_tmp.xyz, gs_out.forward); + pos_tmp.xyz = pos_tmp.xyz - plane_right * (length(frag_pos_end - + frag_pos_start) * shared_uniforms.geometry_thickness); gs_out.frag_position = pos_tmp.xyz; gl_Position = projView * pos_tmp; EmitVertex();