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.py141
1 files changed, 50 insertions, 91 deletions
diff --git a/boltzgas/visual/view.py b/boltzgas/visual/view.py
index c1f92e6..300092f 100644
--- a/boltzgas/visual/view.py
+++ b/boltzgas/visual/view.py
@@ -1,11 +1,12 @@
from OpenGL.GL import *
from OpenGL.GLUT import *
-from pyrr import matrix44, quaternion
+from pyrr import matrix44
import numpy as np
from .shader import Shader
+from .camera import Projection, Rotation, MouseDragMonitor, MouseScrollMonitor
particle_shader = (
"""
@@ -25,9 +26,9 @@ particle_shader = (
n = normalize(n);
vec3 dir = normalize(camera_pos.xyz - particle_pos);
- vec3 color = vec3(1.,1.,1.) * dot(dir, n);
+ vec3 color = vec3(1.) * dot(dir, n);
- gl_FragColor = vec4(color.xyz, 0.0);
+ gl_FragColor = vec4(max(vec3(0.5), color.xyz), 1.0);
}
""",
"""
@@ -58,28 +59,23 @@ decoration_shader = (
"""
#version 430
- in vec3 color;
-
void main(){
- gl_FragColor = vec4(color.xyz, 0.0);
+ gl_FragColor = vec4(1.,1.,1., 1.0);
}
""",
"""
#version 430
- in vec3 vertex;
-
- out vec3 color;
+ layout (location=0) in vec3 vertex;
uniform mat4 projection;
- uniform vec3 face_color;
+ uniform mat4 rotation;
void main() {
- gl_Position = projection * vec4(vertex, 1.);
- color = face_color;
+ gl_Position = projection * rotation * vec4(vertex.xyz, 1.);
}
""",
- ['projection', 'face_color']
+ ['projection', 'rotation']
)
texture_shader = (
@@ -93,7 +89,12 @@ texture_shader = (
uniform float mixing;
void main() {
- gl_FragColor = mix(texture(picture[0], tex_coord), texture(picture[1], tex_coord), mixing);
+ vec3 color = mix(texture(picture[0], tex_coord), texture(picture[1], tex_coord), mixing).xyz;
+ if (color == vec3(0.,0.,0.)) {
+ gl_FragColor = vec4(color, 0.5);
+ } else {
+ gl_FragColor = vec4(color, 1.0);
+ }
}
""",
"""
@@ -115,68 +116,6 @@ texture_shader = (
)
-class Projection:
- def __init__(self, distance):
- self.distance = distance
- self.ratio = 4./3.
- self.update()
-
- def update(self):
- projection = matrix44.create_perspective_projection(20.0, self.ratio, 0.1, 5000.0)
- look = matrix44.create_look_at(
- eye = [0, 0, -self.distance],
- target = [0, 0, 0],
- up = [0,-1, 0])
-
- self.matrix = np.matmul(look, projection)
-
- def update_ratio(self, width, height, update_viewport = True):
- if update_viewport:
- glViewport(0,0,width,height)
-
- self.ratio = width/height
- self.update()
-
- def update_distance(self, change):
- self.distance += change
- self.update()
-
- def get(self):
- return self.matrix
-
-class Rotation:
- def __init__(self, shift, x = np.pi, z = np.pi):
- self.matrix = matrix44.create_from_translation(shift),
- self.rotation_x = quaternion.Quaternion()
- self.update(x,z)
-
- def shift(self, x, z):
- self.matrix = np.matmul(
- self.matrix,
- matrix44.create_from_translation([x,0,z])
- )
- self.inverse_matrix = np.linalg.inv(self.matrix)
-
- def update(self, x, z):
- rotation_x = quaternion.Quaternion(quaternion.create_from_eulers([x,0,0]))
- rotation_z = self.rotation_x.conjugate.cross(
- quaternion.Quaternion(quaternion.create_from_eulers([0,0,z])))
- self.rotation_x = self.rotation_x.cross(rotation_x)
-
- self.matrix = np.matmul(
- self.matrix,
- matrix44.create_from_quaternion(rotation_z.cross(self.rotation_x))
- )
- self.inverse_matrix = np.linalg.inv(self.matrix)
-
- def get(self):
- return self.matrix
-
- def get_inverse(self):
- return self.inverse_matrix
-
-
-
class View:
def __init__(self, gas, decorations, windows):
self.gas = gas
@@ -187,9 +126,18 @@ class View:
self.particle_shader = Shader(*particle_shader)
self.decoration_shader = Shader(*decoration_shader)
- self.projection3d = Projection(distance = 6)
- self.rotation3d = Rotation([-1, -1, -1/2], 5*np.pi/4, np.pi/4)
- self.camera_pos = np.matmul([0,self.projection3d.distance,0,1], self.rotation3d.get_inverse())
+ self.camera_projection = Projection(distance = 6)
+ self.camera_rotation = Rotation([-1/2, -1/2, -1/2])
+ self.camera_pos = np.matmul([0,-self.camera_projection.distance,0,1], self.camera_rotation.get_inverse())
+
+ self.mouse_monitors = [
+ MouseDragMonitor(GLUT_LEFT_BUTTON, lambda dx, dy: self.camera_rotation.update(0.005*dy, 0.005*dx)),
+ MouseDragMonitor(GLUT_RIGHT_BUTTON, lambda dx, dy: self.camera_projection.shift(0.005*dx, 0.005*dy)),
+ MouseScrollMonitor(lambda zoom: self.camera_projection.update_distance(0.1*zoom))
+ ]
+
+ self.show_histogram = False
+
def reshape(self, width, height):
glViewport(0,0,width,height)
@@ -202,6 +150,8 @@ class View:
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.camera_projection.update_ratio(width, height)
+
self.pixels_per_unit = height / world_height
self.projection = np.matmul(translation, projection)
@@ -209,21 +159,16 @@ class View:
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)
+ glEnable(GL_DEPTH_TEST)
+ glDepthMask(GL_TRUE)
+ glDepthFunc(GL_LEQUAL)
- 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)
+ glEnable(GL_BLEND)
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
self.particle_shader.use()
- #glUniformMatrix4fv(self.particle_shader.uniform['projection'], 1, False, np.asfortranarray(self.projection))
-
- glUniformMatrix4fv(self.particle_shader.uniform['projection'], 1, False, np.ascontiguousarray(self.projection3d.get()))
- glUniformMatrix4fv(self.particle_shader.uniform['rotation'], 1, False, np.ascontiguousarray(self.rotation3d.get()))
+ glUniformMatrix4fv(self.particle_shader.uniform['projection'], 1, False, np.ascontiguousarray(self.camera_projection.get()))
+ glUniformMatrix4fv(self.particle_shader.uniform['rotation'], 1, False, np.ascontiguousarray(self.camera_rotation.get()))
glUniform3f(self.particle_shader.uniform['face_color'], 1., 1., 1.)
glUniform3f(self.particle_shader.uniform['trace_color'], 1., 0., 0.)
@@ -233,5 +178,19 @@ class View:
glEnable(GL_POINT_SPRITE)
glPointSize(2*self.gas.radius*self.pixels_per_unit)
self.gas.gl_draw_particles()
+ glBindVertexArray(0)
+
+ self.decoration_shader.use()
+ glUniformMatrix4fv(self.decoration_shader.uniform['projection'], 1, False, np.ascontiguousarray(self.camera_projection.get()))
+ glUniformMatrix4fv(self.decoration_shader.uniform['rotation'], 1, False, np.ascontiguousarray(self.camera_rotation.get()))
+ glLineWidth(2)
+ for decoration in self.decorations:
+ decoration.display(self.decoration_shader.uniform)
+
+ if self.show_histogram:
+ 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)
glutSwapBuffers()