diff options
| -rw-r--r-- | boltzgas/visual/shader.py | 15 | ||||
| -rw-r--r-- | boltzgas/visual/view.py | 78 | 
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)  | 
