aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2020-03-28 19:55:14 +0100
committerAdrian Kummerlaender2020-03-28 19:55:14 +0100
commit26e09c9f01eaf997b0b4f8fa831ed3873f66465a (patch)
tree8bee2f2ffbbb9f3f84f255aa46891efc19a5d050
parent5e99925cd258ff68f1da7ce0bdb823efe785d8de (diff)
downloadboltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar.gz
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar.bz2
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar.lz
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar.xz
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.tar.zst
boltzgas-26e09c9f01eaf997b0b4f8fa831ed3873f66465a.zip
Draw spheres in correct size
…using billboarding.
-rw-r--r--boltzgas/visual/shader.py15
-rw-r--r--boltzgas/visual/view.py78
2 files changed, 74 insertions, 19 deletions
diff --git a/boltzgas/visual/shader.py b/boltzgas/visual/shader.py
index b4295a8..c6c035b 100644
--- a/boltzgas/visual/shader.py
+++ b/boltzgas/visual/shader.py
@@ -1,4 +1,4 @@
-from OpenGL.GL import GL_VERTEX_SHADER, GL_FRAGMENT_SHADER
+from OpenGL.GL import GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, GL_GEOMETRY_SHADER
from OpenGL.GL import shaders
class Shader:
@@ -13,3 +13,16 @@ class Shader:
def use(self):
shaders.glUseProgram(self.program)
+class GeometryShader:
+ def __init__(self, fragment_src, geometry_src, vertex_src, uniform):
+ self.program = shaders.compileProgram(
+ shaders.compileShader(vertex_src, GL_VERTEX_SHADER),
+ shaders.compileShader(geometry_src, GL_GEOMETRY_SHADER),
+ shaders.compileShader(fragment_src, GL_FRAGMENT_SHADER))
+ self.uniform = { }
+ for name in uniform:
+ self.uniform[name] = shaders.glGetUniformLocation(self.program, name)
+
+ def use(self):
+ shaders.glUseProgram(self.program)
+
diff --git a/boltzgas/visual/view.py b/boltzgas/visual/view.py
index bdc18e8..7d7d2cc 100644
--- a/boltzgas/visual/view.py
+++ b/boltzgas/visual/view.py
@@ -5,7 +5,7 @@ from pyrr import matrix44
import numpy as np
-from .shader import Shader
+from .shader import Shader, GeometryShader
from .camera import Projection, Rotation, MouseDragMonitor, MouseScrollMonitor
particle_shader = (
@@ -16,43 +16,86 @@ particle_shader = (
uniform vec4 camera_pos;
+ in GS_OUT
+ {
+ vec3 particle_pos;
+ vec2 tex_coord;
+ } fs_in;
+
void main(){
- if (length(gl_PointCoord - vec2(0.5)) > 0.5) {
+ if (length(fs_in.tex_coord - vec2(0.5)) > 0.5) {
discard;
}
- vec3 n = vec3(gl_PointCoord - vec2(0.5), 0.);
+ vec3 n = vec3(fs_in.tex_coord - vec2(0.5), 0.);
n.z = -sqrt(1.0 - length(n));
n = normalize(n);
- vec3 dir = normalize(camera_pos.xyz - particle_pos);
- vec3 color = vec3(1.) * dot(dir, n);
+ vec3 dir = normalize(camera_pos.xyz - fs_in.particle_pos);
+ vec3 color = vec3(1.) * max(0., dot(dir, n));
- gl_FragColor = vec4(max(vec3(0.5), color.xyz), 1.0);
+ gl_FragColor = vec4(color.xyz, 1.0);
}
""",
"""
#version 430
- layout (location=0) in vec4 particles;
+ layout (points) in;
+ layout (triangle_strip, max_vertices=4) out;
- out vec3 color;
- out vec3 particle_pos;
+ out GS_OUT
+ {
+ vec3 particle_pos;
+ vec2 tex_coord;
+ } gs_out;
uniform mat4 projection;
uniform mat4 rotation;
- uniform vec3 face_color;
- uniform vec3 trace_color;
- uniform uint trace_id;
uniform vec4 camera_pos;
+ uniform float radius;
+
+ vec4 project(vec3 v) {
+ return projection * rotation * vec4(v, 1.);
+ }
+
+ void emitSquareAt(vec3 position) {
+ mat4 m = projection * rotation;
+ vec3 camera_right = normalize(vec3(m[0][0], m[1][0], m[2][0]));
+ vec3 camera_up = normalize(vec3(m[0][1], m[1][1], m[2][1]));
+
+ gs_out.particle_pos = gl_in[0].gl_Position.xyz;
+
+ gl_Position = project(position + camera_right * -radius + camera_up * -radius);
+ gs_out.tex_coord = vec2(0.,0.);
+ EmitVertex();
+ gl_Position = project(position + camera_right * radius + camera_up * -radius);
+ gs_out.tex_coord = vec2(1.,0.);
+ EmitVertex();
+ gl_Position = project(position + camera_right * -radius + camera_up * radius);
+ gs_out.tex_coord = vec2(0.,1.);
+ EmitVertex();
+ gl_Position = project(position + camera_right * radius + camera_up * radius);
+ gs_out.tex_coord = vec2(1.,1.);
+ EmitVertex();
+ }
+
+ void main() {
+ emitSquareAt(gl_in[0].gl_Position.xyz);
+ EndPrimitive();
+ }
+ """,
+ """
+ #version 430
+
+ layout (location=0) in vec4 particle_pos;
+
void main() {
- gl_Position = projection * rotation * vec4(particles.xyz, 1.);
- particle_pos = gl_Position.xyz;
+ gl_Position = vec4(particle_pos.xyz, 1.0);
}
""",
- ['projection', 'rotation', 'camera_pos']
+ ['projection', 'rotation', 'camera_pos', 'radius']
)
decoration_shader = (
@@ -122,7 +165,7 @@ class View:
self.instruments = instruments
self.texture_shader = Shader(*texture_shader)
- self.particle_shader = Shader(*particle_shader)
+ self.particle_shader = GeometryShader(*particle_shader)
self.decoration_shader = Shader(*decoration_shader)
self.camera_projection = Projection(distance = 5)
@@ -169,9 +212,8 @@ class View:
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()))
glUniform4fv(self.particle_shader.uniform['camera_pos'], 1, self.camera_pos)
+ glUniform1f(self.particle_shader.uniform['radius'], self.gas.radius)
- glEnable(GL_POINT_SPRITE)
- glPointSize(2*self.gas.radius*self.pixels_per_unit)
self.gas.gl_draw_particles()
glBindVertexArray(0)