layout(lines, invocations=2) in; layout(triangle_strip, max_vertices=8) out; out vec4 fcolor; in vec4 fca[]; uniform mat4 mvp; uniform float fruitdrop; uniform float wind; in int gl_InvocationID; void emitsimple(vec4 position){ gl_Position = mvp * position; fcolor = fca[0]; EmitVertex(); } void emitpanel(vec4 start, vec4 end, vec4 addition){ emitsimple(start + addition); emitsimple(start - addition); emitsimple(end + addition); emitsimple(end - addition); EndPrimitive(); } void branch(vec4 start, vec4 end){ // Maybe number of sides as a parameter float thickness = distance(start, end) / 10.0; emitpanel(start, end, vec4(thickness, 0, 0, 0)); emitpanel(start, end, vec4(0, 0, thickness, 0)); } void fvemit(vec4 pos){ gl_Position = mvp * (pos + vec4(0, -min(fruitdrop, pos.y + 2), 0, 0)); fcolor = vec4(1, 0, 0, 1); EmitVertex(); } void makefruit(vec4 spot, float size){ vec4 a = spot + vec4(-size, -size, -size, 0); vec4 b = spot + vec4(size, -size, -size, 0); vec4 c = spot + vec4(0, -size, size, 0); vec4 d = spot + vec4(0, size, 0, 0); fvemit(a); fvemit(b); fvemit(c); fvemit(d); fvemit(b); fvemit(a); } void main(){ vec4 start = gl_in[0].gl_Position; vec4 end = gl_in[1].gl_Position; if(gl_InvocationID == 0 || fruitdrop == 0.0){ if(start.y > -2) start.x += (start.y + 2) / 5.0 * wind; if(end.y > -2) end.x += (end.y + 2) / 5.0 * wind; } if(gl_InvocationID == 0){ branch(start, end); } else if(gl_InvocationID == 1) { if(distance(start, end) < .1){ makefruit(end, .05); } } }