From b770e7452c11cf0acdccf824c9c9304e9de3f08b Mon Sep 17 00:00:00 2001 From: Adrian Kummerlaender Date: Sat, 21 Sep 2019 18:19:22 +0200 Subject: Extract GL moments, particle buffers and add texture buffer --- utility/opengl.py | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 utility/opengl.py (limited to 'utility/opengl.py') diff --git a/utility/opengl.py b/utility/opengl.py new file mode 100644 index 0000000..afbfa00 --- /dev/null +++ b/utility/opengl.py @@ -0,0 +1,136 @@ +import pyopencl as cl +mf = cl.mem_flags + +import numpy +import sympy + +from mako.template import Template +from pathlib import Path + +from OpenGL.GL import * +from OpenGL.arrays import vbo + +class MomentsVertexBuffer: + def __init__(self, lattice): + self.lattice = lattice + + self.np_moments = numpy.ndarray(shape=(self.lattice.memory.volume, 4), dtype=self.lattice.memory.float_type) + self.gl_moments = vbo.VBO(data=self.np_moments, usage=GL_DYNAMIC_DRAW, target=GL_ARRAY_BUFFER) + self.gl_moments.bind() + self.cl_gl_moments = cl.GLBuffer(self.lattice.context, mf.READ_WRITE, int(self.gl_moments)) + + self.build_kernel() + + def build_kernel(self): + program_src = Template(filename = str(Path(__file__).parent/'../template/opengl.mako')).render( + descriptor = self.lattice.descriptor, + geometry = self.lattice.geometry, + memory = self.lattice.memory, + + moments_subexpr = self.lattice.moments[0], + moments_assignment = self.lattice.moments[1], + collide_subexpr = self.lattice.collide[0], + collide_assignment = self.lattice.collide[1], + + float_type = self.lattice.float_type[1], + + ccode = sympy.ccode + ) + self.program = cl.Program(self.lattice.context, program_src).build(self.lattice.compiler_args) + + def bind(self): + self.gl_moments.bind() + glEnableClientState(GL_VERTEX_ARRAY) + glVertexPointer(4, GL_FLOAT, 0, self.gl_moments) + + def collect(self): + cl.enqueue_acquire_gl_objects(self.lattice.queue, [self.cl_gl_moments]) + + if self.lattice.tick: + self.program.collect_gl_moments( + self.lattice.queue, + self.lattice.grid.size(), + self.lattice.layout, + self.lattice.memory.cl_pop_b, + self.lattice.memory.cl_material, + self.cl_gl_moments) + else: + self.program.collect_gl_moments( + self.lattice.queue, + self.lattice.grid.size(), + self.lattice.layout, + self.lattice.memory.cl_pop_a, + self.lattice.memory.cl_material, + self.cl_gl_moments) + + +class MomentsTexture: + def __init__(self, lattice): + self.lattice = lattice + self.gl_texture_buffer = numpy.ndarray(shape=(self.lattice.memory.volume, 4), dtype=self.lattice.memory.float_type) + self.gl_texture_buffer[:,:] = 0.0 + + self.gl_moments = glGenTextures(1) + self.gl_texture_type = {2: GL_TEXTURE_2D, 3: GL_TEXTURE_3D}.get(self.lattice.descriptor.d) + glBindTexture(self.gl_texture_type, self.gl_moments) + + if self.gl_texture_type == GL_TEXTURE_3D: + glTexImage3D(self.gl_texture_type, 0, GL_RGBA, self.lattice.memory.size_x, self.lattice.memory.size_y, self.lattice.memory.size_z, 0, GL_RGBA, GL_FLOAT, self.gl_texture_buffer) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(self.gl_texture_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE) + self.cl_gl_moments = cl.GLTexture(self.lattice.context, mf.READ_WRITE, self.gl_texture_type, 0, self.gl_moments, 3) + elif self.gl_texture_type == GL_TEXTURE_2D: + glTexImage2D(self.gl_texture_type, 0, GL_RGBA, self.lattice.memory.size_x, self.lattice.memory.size_y, 0, GL_RGBA, GL_FLOAT, self.gl_texture_buffer) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(self.gl_texture_type, GL_TEXTURE_MAG_FILTER, GL_NEAREST) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) + glTexParameteri(self.gl_texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) + self.cl_gl_moments = cl.GLTexture(self.lattice.context, mf.READ_WRITE, self.gl_texture_type, 0, self.gl_moments, 2) + + self.build_kernel() + + def build_kernel(self): + program_src = Template(filename = str(Path(__file__).parent/'../template/opengl.mako')).render( + descriptor = self.lattice.descriptor, + geometry = self.lattice.geometry, + memory = self.lattice.memory, + + moments_subexpr = self.lattice.moments[0], + moments_assignment = self.lattice.moments[1], + collide_subexpr = self.lattice.collide[0], + collide_assignment = self.lattice.collide[1], + + float_type = self.lattice.float_type[1], + + ccode = sympy.ccode + ) + self.program = cl.Program(self.lattice.context, program_src).build(self.lattice.compiler_args) + + def bind(self, location = GL_TEXTURE0): + glEnable(self.gl_texture_type) + glActiveTexture(location); + glBindTexture(self.gl_texture_type, self.gl_moments) + + def collect(self): + cl.enqueue_acquire_gl_objects(self.lattice.queue, [self.cl_gl_moments]) + + if self.lattice.tick: + self.program.collect_gl_moments_to_texture( + self.lattice.queue, + self.lattice.grid.size(), + self.lattice.layout, + self.lattice.memory.cl_pop_b, + self.lattice.memory.cl_material, + self.cl_gl_moments) + else: + self.program.collect_gl_moments_to_texture( + self.lattice.queue, + self.lattice.grid.size(), + self.lattice.layout, + self.lattice.memory.cl_pop_a, + self.lattice.memory.cl_material, + self.cl_gl_moments) + -- cgit v1.2.3