def initializeGL(self): try: GL.Init() GL.Viewport(0, 0, context['width'], context['height']) vert = GL.NewVertexShader(''' #version 430 in vec2 vert; out vec3 frag_vert; uniform float ratio; uniform vec3 position; uniform vec3 target; void main() { vec3 X = normalize(position - target); vec3 Y = normalize(cross(X, vec3(0.0, 0.0, 1.0))); vec3 Z = normalize(cross(X, Y)); mat3 M = mat3(X, Y, Z); gl_Position = vec4(vert, 0.0, 1.0); frag_vert = M * vec3(1.0, vert.x * ratio, vert.y); } ''') frag = GL.NewFragmentShader(''' #version 430 struct Face { vec4 color; vec3 T1, T2_T1, T3_T1, T2_T1_C_T3_T1, N; }; in vec3 frag_vert; out vec4 frag; uniform vec3 position; layout (binding = 1) buffer Input { int faces; Face face[]; }; void main() { float factor = 1.0; vec3 R1 = position; vec3 R1_R2 = normalize(frag_vert); vec3 color = vec3(0.0, 0.0, 0.0); for (int h = 0; h < 5; ++h) { int hit = 0; float dist = -1; for (int i = 0; i < faces; ++i) { vec3 T1 = face[i].T1; float f = dot(R1_R2, face[i].N); if (f <= 0.0) continue; float D = dot(R1_R2, face[i].T2_T1_C_T3_T1); if (D == 0.0) continue; vec3 R1_T1 = R1 - T1; float u = dot(R1_T1, face[i].T2_T1_C_T3_T1) / D; if (u < 0.0 || (dist > 0.0 && dist < u)) continue; vec3 R1_R2_C_R1_T1 = cross(R1_R2, R1_T1); float v = dot(face[i].T3_T1, R1_R2_C_R1_T1) / D; if (v < 0.0 || v > 1.0) continue; float w = -dot(face[i].T2_T1, R1_R2_C_R1_T1) / D; if (w < 0.0 || w > 1.0) continue; dist = u; hit = i; } if (dist > 0) { float g = dot(R1_R2, face[hit].N); color += face[hit].color.rgb * factor * g; R1 = R1 - R1_R2 * dist; R1_R2 = reflect(R1_R2, face[hit].N); factor *= 1.0 - face[hit].color.a; if (factor < 0.01) break; } else { break; } } frag = vec4(color, 1.0); } ''') prog = GL.NewProgram([vert, frag]) vbo = GL.NewVertexBuffer(struct.pack('8f', -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0)) context['vao'] = GL.NewVertexArray(prog, vbo, '2f', ['vert']) ssbo = GL.NewStorageBuffer(open('../DataFiles/Raytrace-scene.dat', 'rb').read()) GL.UseStorageBuffer(ssbo, 1) GL.SetUniform(prog['ratio'], context['width'] / context['height']) GL.SetUniform(prog['position'], 0.7, 0.7, 0.0) GL.SetUniform(prog['target'], 0, 0, 0) except GL.Error as error: print(error) exit(1)
} } frag = vec4(color, 1.0); } ''') prog = GL.NewProgram([vert, frag]) vbo = GL.NewVertexBuffer( struct.pack('8f', -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0)) vao = GL.NewVertexArray(prog, vbo, '2f', ['vert']) ssbo = GL.NewStorageBuffer( open('../DataFiles/Raytrace-scene.dat', 'rb').read()) GL.UseStorageBuffer(ssbo, 1) GL.SetUniform(prog['ratio'], 16 / 9) x, y = 0.0, 0.0 while WND.Update(): GL.Clear(240, 240, 240) if WND.KeyDown('A'): x -= 0.04 if WND.KeyDown('D'): x += 0.04 if WND.KeyDown('W'): y += 0.04 if WND.KeyDown('S'):
(-400, -200, 100), (-250, -350, 100), (0, -300, 100), (250, -350, 100), (400, -200, 100), ] circles_ubo = GL.NewUniformBuffer(struct.pack('i4x', len(circles)) + b''.join(struct.pack('2f1f4x', *c) for c in circles)) GL.UseUniformBuffer(circles_ubo, circles_prog['Circles']) particles_prog = GL.NewProgram([particles_vert, particles_frag]) GL.SetUniform(particles_prog['scale'], 0.002 * height / width, 0.002) particle_vbo = GL.NewVertexBuffer(b''.join(struct.pack('2f', cos(i * 2 * pi / 16), sin(i * 2 * pi / 16)) for i in range(16))) particle_vao = GL.NewVertexArray(particles_prog, particle_vbo, '2f', ['vert']) sbo = GL.NewStorageBuffer(b''.join(struct.pack('ffffff', -10000, 0, -10000, 0, 0, 0) for i in range(10240))) GL.UseUniformBuffer(circles_ubo, circles_prog['Circles']) GL.UseStorageBuffer(sbo) k = 0 while WND.Update(): k = (k + 32) % 10240 GL.UpdateStorageBuffer(sbo, k * 24, b''.join(struct.pack('ffffff', -400, 200, -400 + uniform(3, 5), 200 + uniform(2, 5), 0, -0.1) for i in range(32))) GL.Clear(240, 240, 240) GL.RunComputeShader(physics, 40) GL.RenderTriangleFan(circle_vao, 128, instances = len(circles)) GL.RenderTriangleFan(particle_vao, 16, instances = 10240)
layout (local_size_x = 2, local_size_y = 2, local_size_z = 2) in; void main() { B[gl_GlobalInvocationID.x][gl_GlobalInvocationID.y][gl_GlobalInvocationID.z] = A[gl_GlobalInvocationID.x][gl_GlobalInvocationID.y][gl_GlobalInvocationID.z]; } ''') A = GL.NewStorageBuffer(struct.pack('64i', *[1 + i for i in range(64)])) B = GL.NewStorageBuffer(b'\x00' * 256) C = GL.NewStorageBuffer(b'\x00' * 256) BX = GL.NewStorageBuffer(b'\x00' * 256) BY = GL.NewStorageBuffer(b'\x00' * 256) BZ = GL.NewStorageBuffer(b'\x00' * 256) GL.UseStorageBuffer(A) GL.UseStorageBuffer(B, 1) GL.RunComputeShader(cs) GL.UseStorageBuffer(BX, 1) GL.RunComputeShader(cs, x = 2) GL.UseStorageBuffer(BY, 1) GL.RunComputeShader(cs, y = 2) GL.UseStorageBuffer(BZ, 1) GL.RunComputeShader(cs, z = 2) GL.UpdateStorageBuffer(C, 0, struct.pack('64i', *[4 for i in range(64)])) GL.UpdateStorageBuffer(C, 64, struct.pack('32i', *[9 for i in range(32)])) print(struct.unpack('64i', GL.ReadStorageBuffer(B)))