aboutsummaryrefslogtreecommitdiff
path: root/boltzgas/visual/view.py
diff options
context:
space:
mode:
Diffstat (limited to 'boltzgas/visual/view.py')
-rw-r--r--boltzgas/visual/view.py154
1 files changed, 154 insertions, 0 deletions
diff --git a/boltzgas/visual/view.py b/boltzgas/visual/view.py
new file mode 100644
index 0000000..d6e188b
--- /dev/null
+++ b/boltzgas/visual/view.py
@@ -0,0 +1,154 @@
+from OpenGL.GL import *
+from OpenGL.GLUT import *
+
+from pyrr import matrix44
+
+import numpy as np
+
+from .shader import Shader
+
+particle_shader = (
+ """
+ #version 430
+
+ in vec3 color;
+
+ void main(){
+ if (length(gl_PointCoord - vec2(0.5)) > 0.5) {
+ discard;
+ }
+
+ gl_FragColor = vec4(color.xyz, 0.0);
+ }
+ """,
+ """
+ #version 430
+
+ layout (location=0) in vec2 particles;
+
+ out vec3 color;
+
+ uniform mat4 projection;
+ uniform vec3 face_color;
+ uniform vec3 trace_color;
+ uniform uint trace_id;
+
+ void main() {
+ gl_Position = projection * vec4(particles, 0., 1.);
+
+ if (gl_VertexID == trace_id) {
+ color = trace_color;
+ } else {
+ color = face_color;
+ }
+ }
+ """,
+ ['projection', 'face_color', 'trace_color', 'trace_id']
+)
+
+decoration_shader = (
+ """
+ #version 430
+
+ in vec3 color;
+
+ void main(){
+ gl_FragColor = vec4(color.xyz, 0.0);
+ }
+ """,
+ """
+ #version 430
+
+ in vec3 vertex;
+
+ out vec3 color;
+
+ uniform mat4 projection;
+ uniform vec3 face_color;
+
+ void main() {
+ gl_Position = projection * vec4(vertex, 1.);
+ color = face_color;
+ }
+ """,
+ ['projection', 'face_color']
+)
+
+texture_shader = (
+ """
+ #version 430
+
+ in vec2 tex_coord;
+
+ uniform sampler2D picture[2];
+
+ uniform float mixing;
+
+ void main() {
+ gl_FragColor = mix(texture(picture[0], tex_coord), texture(picture[1], tex_coord), mixing);
+ }
+ """,
+ """
+ #version 430
+
+ layout (location=0) in vec2 screen_vertex;
+ layout (location=1) in vec2 texture_vertex;
+
+ out vec2 tex_coord;
+
+ uniform mat4 projection;
+
+ void main() {
+ gl_Position = projection * vec4(screen_vertex, 0.0, 1.0);
+ tex_coord = texture_vertex;
+ }
+ """,
+ ['picture','projection','mixing']
+)
+
+class View:
+ def __init__(self, gas, decorations, windows):
+ self.gas = gas
+ self.decorations = decorations
+ self.windows = windows
+
+ self.texture_shader = Shader(*texture_shader)
+ self.particle_shader = Shader(*particle_shader)
+ self.decoration_shader = Shader(*decoration_shader)
+
+ def reshape(self, width, height):
+ glViewport(0,0,width,height)
+
+ world_height = 1.4
+ world_width = world_height / height * width
+
+ projection = matrix44.create_orthogonal_projection(-world_width/2, world_width/2, -world_height/2, world_height/2, -1, 1)
+ translation = matrix44.create_from_translation([-1.05, -1.0/2, 0])
+
+ self.pixels_per_unit = height / world_height
+ self.projection = np.matmul(translation, projection)
+
+ def display(self):
+ glClearColor(0.,0.,0.,1.)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+
+ self.decoration_shader.use()
+ glUniformMatrix4fv(self.decoration_shader.uniform['projection'], 1, False, np.asfortranarray(self.projection))
+ for decoration in self.decorations:
+ decoration.display(self.decoration_shader.uniform)
+
+ self.texture_shader.use()
+ glUniformMatrix4fv(self.texture_shader.uniform['projection'], 1, False, np.asfortranarray(self.projection))
+ for window in self.windows:
+ window.display(self.texture_shader.uniform)
+
+ self.particle_shader.use()
+ glUniformMatrix4fv(self.particle_shader.uniform['projection'], 1, False, np.asfortranarray(self.projection))
+ glUniform3f(self.particle_shader.uniform['face_color'], 1., 1., 1.)
+ glUniform3f(self.particle_shader.uniform['trace_color'], 1., 0., 0.)
+ glUniform1ui(self.particle_shader.uniform['trace_id'], 4)
+ glEnable(GL_POINT_SPRITE)
+ glPointSize(2*self.gas.radius*self.pixels_per_unit)
+ self.gas.gl_draw_particles()
+
+ glutSwapBuffers()