aboutsummaryrefslogtreecommitdiff
path: root/utility/opengl.py
blob: afbfa00f91041c5eb95eb187d1e3eb8794ebe89a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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)