Ejemplo n.º 1
0
    def _create_device_objects(self):
        # save state
        last_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture))
        last_array_buffer = gl.GLint()
        gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer))

        last_vertex_array = gl.GLint()
        gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array))

        self._shader_handle = gl.glCreateProgram()
        # note: no need to store shader parts handles after linking
        vertex_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER)
        fragment_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)

        gl.glShaderSource(vertex_shader, 1, make_string_buffer(self.VERTEX_SHADER_SRC), None)
        gl.glShaderSource(fragment_shader, 1, make_string_buffer(self.FRAGMENT_SHADER_SRC), None)
        gl.glCompileShader(vertex_shader)
        gl.glCompileShader(fragment_shader)

        gl.glAttachShader(self._shader_handle, vertex_shader)
        gl.glAttachShader(self._shader_handle, fragment_shader)

        gl.glLinkProgram(self._shader_handle)

        # note: after linking shaders can be removed
        gl.glDeleteShader(vertex_shader)
        gl.glDeleteShader(fragment_shader)

        self._attrib_location_tex = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"Texture"))
        self._attrib_proj_mtx = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"ProjMtx"))
        self._attrib_location_position = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Position"))
        self._attrib_location_uv = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"UV"))
        self._attrib_location_color = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Color"))

        self._vbo_handle = gl.GLuint()
        gl.glGenBuffers(1, byref(self._vbo_handle))
        self._elements_handle = gl.GLuint()
        gl.glGenBuffers(1, byref(self._elements_handle))

        self._vao_handle = gl.GLuint()
        gl.glGenVertexArrays(1, byref(self._vao_handle))
        gl.glBindVertexArray(self._vao_handle)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle)

        gl.glEnableVertexAttribArray(self._attrib_location_position)
        gl.glEnableVertexAttribArray(self._attrib_location_uv)
        gl.glEnableVertexAttribArray(self._attrib_location_color)

        gl.glVertexAttribPointer(self._attrib_location_position, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_POS_OFFSET))
        gl.glVertexAttribPointer(self._attrib_location_uv, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_UV_OFFSET))
        gl.glVertexAttribPointer(self._attrib_location_color, 4, gl.GL_UNSIGNED_BYTE, gl.GL_TRUE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_COL_OFFSET))

        # restore state

        gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents)
        gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents)
Ejemplo n.º 2
0
def get_uniform_data(program):
    """
    Args:
        program:

    Returns:

    """
    uniforms = {}

    count = pointer(GLint())
    buffer_size = GLsizei(32)
    length = GLsizei()
    size = GLint()
    data_type = GLenum()
    uniform_name = c_string('', size=buffer_size.value)

    glGetProgramiv(program, GL_ACTIVE_UNIFORMS, count)

    for i in range(count.contents.value):
        glGetActiveUniform(program, GLuint(i), buffer_size, length, size,
                           data_type, uniform_name)
        uniform_name_ = uniform_name.value.decode('utf-8')
        data_type_string = temp[data_type.value]
        uniforms[uniform_name_] = {
            'dtype': table[data_type_string]['dtype'],
            'index': i,
            'size': size.value,
            'value': None,
            'location': glGetUniformLocation(program, uniform_name),
            'function': table[data_type_string]['function'],
        }
        print(uniform_name_, uniforms[uniform_name_])
    return uniforms
Ejemplo n.º 3
0
 def draw(self):
     """Draw the object to the display buffer"""
     from pyglet import gl
     gl.glUseProgram(self._program)
     for kind in ('fill', 'line'):
         if self._counts[kind] > 0:
             if kind == 'line':
                 if self._line_width <= 0.0:
                     continue
                 gl.glLineWidth(self._line_width)
                 if self._line_loop:
                     mode = gl.GL_LINE_LOOP
                 else:
                     mode = gl.GL_LINE_STRIP
                 cmd = partial(gl.glDrawArrays, mode, 0, self._counts[kind])
             else:
                 gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER,
                                 self._buffers[kind]['index'])
                 cmd = partial(gl.glDrawElements, gl.GL_TRIANGLES,
                               self._counts[kind], gl.GL_UNSIGNED_INT, 0)
             gl.glBindBuffer(gl.GL_ARRAY_BUFFER,
                             self._buffers[kind]['array'])
             loc_pos = gl.glGetAttribLocation(self._program, b'a_position')
             gl.glEnableVertexAttribArray(loc_pos)
             gl.glVertexAttribPointer(loc_pos, 2, gl.GL_FLOAT, gl.GL_FALSE,
                                      0, 0)
             loc_col = gl.glGetUniformLocation(self._program, b'u_color')
             gl.glUniform4f(loc_col, *self._colors[kind])
             cmd()
             # The following line is probably only necessary because
             # Pyglet makes some assumptions about the GL state that
             # it perhaps shouldn't. Without it, Text might not
             # render properly (see #252)
             gl.glDisableVertexAttribArray(loc_pos)
     gl.glUseProgram(0)
Ejemplo n.º 4
0
 def draw(self):
     """Draw the object to the display buffer"""
     from pyglet import gl
     gl.glUseProgram(self._program)
     for kind in ('fill', 'line'):
         if self._counts[kind] > 0:
             if kind == 'line':
                 if self._line_width <= 0.0:
                     continue
                 gl.glLineWidth(self._line_width)
                 if self._line_loop:
                     mode = gl.GL_LINE_LOOP
                 else:
                     mode = gl.GL_LINE_STRIP
                 cmd = partial(gl.glDrawArrays, mode, 0, self._counts[kind])
             else:
                 gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER,
                                 self._buffers[kind]['index'])
                 cmd = partial(gl.glDrawElements, gl.GL_TRIANGLES,
                               self._counts[kind], gl.GL_UNSIGNED_INT, 0)
             gl.glBindBuffer(gl.GL_ARRAY_BUFFER,
                             self._buffers[kind]['array'])
             loc_pos = gl.glGetAttribLocation(self._program, b'a_position')
             gl.glEnableVertexAttribArray(loc_pos)
             gl.glVertexAttribPointer(loc_pos, 2, gl.GL_FLOAT, gl.GL_FALSE,
                                      0, 0)
             loc_col = gl.glGetUniformLocation(self._program, b'u_color')
             gl.glUniform4f(loc_col, *self._colors[kind])
             cmd()
             # The following line is probably only necessary because
             # Pyglet makes some assumptions about the GL state that
             # it perhaps shouldn't. Without it, Text might not
             # render properly (see #252)
             gl.glDisableVertexAttribArray(loc_pos)
     gl.glUseProgram(0)
Ejemplo n.º 5
0
 def set_uniformf(self, name, *vals):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     { 1: gl.glUniform1f,
         2: gl.glUniform2f,
         3: gl.glUniform3f,
         4: gl.glUniform4f
     }[len(vals)](location, *vals)
Ejemplo n.º 6
0
 def set_uniformi(self, name, *vals):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     { 1: gl.glUniform1i,
       2: gl.glUniform2i,
       3: gl.glUniform3i,
       4: gl.glUniform4i
     }[len(vals)](location, *vals)
Ejemplo n.º 7
0
 def uniformfv(self, name, size, data):
     data_ctype = (gl.GLfloat * len(data))(*data)
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     {1: gl.glUniform1fv,
      2: gl.glUniform2fv,
      3: gl.glUniform3fv,
      4: gl.glUniform4fv}[len(data) // size](location, size, data_ctype)
Ejemplo n.º 8
0
    def _introspect_uniforms(self):
        for index in range(self.get_num_active(gl.GL_ACTIVE_UNIFORMS)):
            uniform_name, u_type, u_size = self.query_uniform(index)
            loc = gl.glGetUniformLocation(self.prog_id,
                                          uniform_name.encode('utf-8'))

            if loc == -1:  # Skip uniforms that may be in Uniform Blocks
                continue

            try:
                gl_type, gl_setter, length, count = _uniform_setters[u_type]
            except KeyError:
                raise ShaderException(f"Unsupported Uniform type {u_type}")

            gl_getter = _uniform_getters[gl_type]

            is_matrix = u_type in (gl.GL_FLOAT_MAT2, gl.GL_FLOAT_MAT3,
                                   gl.GL_FLOAT_MAT4)

            # Create persistant mini c_array for getters and setters:
            c_array = (gl_type * length)()
            ptr = cast(c_array, POINTER(gl_type))

            # Create custom dedicated getters and setters for each uniform:
            getter = _create_getter_func(self.prog_id, loc, gl_getter, c_array,
                                         length)
            setter = _create_setter_func(loc, gl_setter, c_array, length,
                                         count, ptr, is_matrix)

            # print(f"Found uniform: {uniform_name}, type: {u_type}, size: {u_size}, "
            #       f"location: {loc}, length: {length}, count: {count}")

            self._uniforms[uniform_name] = Uniform(getter, setter)
Ejemplo n.º 9
0
 def uniform2f(self, name, v0, v1):
     self.use()
     loc = gl.glGetUniformLocation(self.handle, ctypes.create_string_buffer(name))
     if loc < 0:
         logging.warning('Uniform {} is not in the shader.'.format(name))
         return
     gl.glUniform2f(loc, v0, v1);
Ejemplo n.º 10
0
    def send(self):

        for name, array in iteritems(self):

            # Attach a shader location value to the array, for quick memory lookup. (gl calls are expensive, for some reason)
            try:
                loc = array.loc
            except AttributeError:
                shader_id = c_int(0)
                gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(shader_id))
                if shader_id.value == 0:
                    raise UnboundLocalError(
                        "Shader not bound to OpenGL context--uniform cannot be sent."
                    )
                array.loc = gl.glGetUniformLocation(shader_id.value,
                                                    name.encode('ascii'))
                loc = array.loc

            if array.ndim == 2:  # Assuming a 4x4 float32 matrix (common for graphics operations)
                try:
                    pointer = array.pointer
                except AttributeError:
                    array.pointer = array.ctypes.data_as(POINTER(c_float *
                                                                 16)).contents
                    pointer = array.pointer
                gl.glUniformMatrix4fv(loc, 1, True, pointer)

            else:
                sendfun = self._sendfuns[array.dtype.kind][
                    len(array) - 1]  # Find correct glUniform function
                sendfun(loc, *array)
Ejemplo n.º 11
0
 def uniform2f(self, name, v0, v1):
     self.use()
     loc = gl.glGetUniformLocation(self.handle,
                                   ctypes.create_string_buffer(name))
     if loc < 0:
         logging.warning('Uniform %s is not in the shader.', name)
         return
     gl.glUniform2f(loc, v0, v1)
Ejemplo n.º 12
0
 def uniformi(self, name, *data):
     location = gl.glGetUniformLocation(self.program, name.encode("ascii"))
     {
         1: gl.glUniform1i,
         2: gl.glUniform2i,
         3: gl.glUniform3i,
         4: gl.glUniform4i
     }[len(data)](location, *data)
Ejemplo n.º 13
0
 def uniformf(self, name, *data):
     location = gl.glGetUniformLocation(self.program, name.encode("ascii"))
     {
         1: gl.glUniform1f,
         2: gl.glUniform2f,
         3: gl.glUniform3f,
         4: gl.glUniform4f
     }[len(data)](location, *data)
Ejemplo n.º 14
0
 def set_uniformi(self, name, *vals):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     {
         1: gl.glUniform1i,
         2: gl.glUniform2i,
         3: gl.glUniform3i,
         4: gl.glUniform4i
     }[len(vals)](location, *vals)
Ejemplo n.º 15
0
 def set_uniformf(self, name, *vals):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     {
         1: gl.glUniform1f,
         2: gl.glUniform2f,
         3: gl.glUniform3f,
         4: gl.glUniform4f
     }[len(vals)](location, *vals)
Ejemplo n.º 16
0
 def uniform1i(self, name, value):
     self.use()
     loc = gl.glGetUniformLocation(self.handle,
                                   ctypes.create_string_buffer(name))
     if loc < 0:
         logging.warning('Uniform {} is not in the shader.'.format(name))
         return
     gl.glUniform1i(loc, value)
Ejemplo n.º 17
0
    def send_to(self, shader):
        """Sends uniform to a currently-bound shader, returning its location (-1 means not sent)"""
        # glGetUniformLocation only needs to be called once, when the shader is linked.  Not a big performance boost, though.
        if type(self.loc) == type(None):
            self.loc = gl.glGetUniformLocation(shader.id, self.name)

        self.sendfun(self.loc, *self.value)
        return self.loc
Ejemplo n.º 18
0
    def uniform_matrixf(self, name, mat):
        ''' Upload uniform matrix, program must be currently bound. '''

        loc = self.uniforms.get(name,
                                gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc

        # Upload the 4x4 floating point matrix
        gl.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))
Ejemplo n.º 19
0
    def __init__(self, ec, fill_color, line_color, line_width, line_loop):
        self._ec = ec
        self._line_width = line_width
        self._line_loop = line_loop  # whether or not lines drawn are looped

        # initialize program and shaders
        from pyglet import gl
        self._program = gl.glCreateProgram()

        vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
        buf = create_string_buffer(tri_vert.encode('ASCII'))
        ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char)))
        gl.glShaderSource(vertex, 1, ptr, None)
        gl.glCompileShader(vertex)
        _check_log(vertex, gl.glGetShaderInfoLog)

        fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
        buf = create_string_buffer(tri_frag.encode('ASCII'))
        ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char)))
        gl.glShaderSource(fragment, 1, ptr, None)
        gl.glCompileShader(fragment)
        _check_log(fragment, gl.glGetShaderInfoLog)

        gl.glAttachShader(self._program, vertex)
        gl.glAttachShader(self._program, fragment)
        gl.glLinkProgram(self._program)
        _check_log(self._program, gl.glGetProgramInfoLog)

        gl.glDetachShader(self._program, vertex)
        gl.glDetachShader(self._program, fragment)
        gl.glUseProgram(self._program)

        # Prepare buffers and bind attributes
        loc = gl.glGetUniformLocation(self._program, b'u_view')
        view = ec.window_size_pix
        view = np.diag([2. / view[0], 2. / view[1], 1., 1.])
        view[-1, :2] = -1
        view = view.astype(np.float32).ravel()
        gl.glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*view))

        self._counts = dict()
        self._colors = dict()
        self._buffers = dict()
        self._points = dict()
        self._tris = dict()
        for kind in ('line', 'fill'):
            self._counts[kind] = 0
            self._colors[kind] = (0., 0., 0., 0.)
            self._buffers[kind] = dict(array=gl.GLuint())
            gl.glGenBuffers(1, pointer(self._buffers[kind]['array']))
        self._buffers['fill']['index'] = gl.GLuint()
        gl.glGenBuffers(1, pointer(self._buffers['fill']['index']))
        gl.glUseProgram(0)

        self.set_fill_color(fill_color)
        self.set_line_color(line_color)
Ejemplo n.º 20
0
    def __init__(self, ec, fill_color, line_color, line_width, line_loop):
        self._ec = ec
        self._line_width = line_width
        self._line_loop = line_loop  # whether or not lines drawn are looped

        # initialize program and shaders
        from pyglet import gl
        self._program = gl.glCreateProgram()

        vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER)
        buf = create_string_buffer(tri_vert.encode('ASCII'))
        ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char)))
        gl.glShaderSource(vertex, 1, ptr, None)
        gl.glCompileShader(vertex)
        _check_log(vertex, gl.glGetShaderInfoLog)

        fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER)
        buf = create_string_buffer(tri_frag.encode('ASCII'))
        ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char)))
        gl.glShaderSource(fragment, 1, ptr, None)
        gl.glCompileShader(fragment)
        _check_log(fragment, gl.glGetShaderInfoLog)

        gl.glAttachShader(self._program, vertex)
        gl.glAttachShader(self._program, fragment)
        gl.glLinkProgram(self._program)
        _check_log(self._program, gl.glGetProgramInfoLog)

        gl.glDetachShader(self._program, vertex)
        gl.glDetachShader(self._program, fragment)
        gl.glUseProgram(self._program)

        # Prepare buffers and bind attributes
        loc = gl.glGetUniformLocation(self._program, b'u_view')
        view = ec.window_size_pix
        view = np.diag([2. / view[0], 2. / view[1], 1., 1.])
        view[-1, :2] = -1
        view = view.astype(np.float32).ravel()
        gl.glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*view))

        self._counts = dict()
        self._colors = dict()
        self._buffers = dict()
        self._points = dict()
        self._tris = dict()
        for kind in ('line', 'fill'):
            self._counts[kind] = 0
            self._colors[kind] = (0., 0., 0., 0.)
            self._buffers[kind] = dict(array=gl.GLuint())
            gl.glGenBuffers(1, pointer(self._buffers[kind]['array']))
        self._buffers['fill']['index'] = gl.GLuint()
        gl.glGenBuffers(1, pointer(self._buffers['fill']['index']))
        gl.glUseProgram(0)

        self.set_fill_color(fill_color)
        self.set_line_color(line_color)
Ejemplo n.º 21
0
 def uniform_matrixf(self, name: str, mat: mat4):
     # upload a uniform matrix
     # works with matrices stored as lists,
     # as well as euclid matrices
     # obtain the uniform location
     location = glGetUniformLocation(self.handle, bytes(name, "utf-8"))
     # upload the 4x4 floating point matrix
     mat_values = (c_float * 16)(*mat.to_list())
     # noinspection PyCallingNonCallable, PyTypeChecker
     glUniformMatrix4fv(location, 1, True, mat_values)
Ejemplo n.º 22
0
 def uniformf(self, name, *vals):
     if len(vals) in range(1, 5):
         # Select the correct function
         {
             1: gl.glUniform1f,
             2: gl.glUniform2f,
             3: gl.glUniform3f,
             4: gl.glUniform4f
             # Retrieve the uniform location, and set
         }[len(vals)](gl.glGetUniformLocation(self.handle, name), *vals)
Ejemplo n.º 23
0
    def __init__(self, game_controller, label: str = None):
        super().__init__(game_controller, label or "Tunnel View 2")

        gl.glClearColor(0.4, 0.65, 0.8, 1.0)
        gl.glEnable(gl.GL_DEPTH_TEST)

        self.ground_level = 0.0
        self.wall_level = 0.75
        gravel_scale = 3.0
        maze = game_controller.maze
        self.ground = GLShape(
            np.array(
                [
                    ((-1, self.ground_level, 1), (0.0, 0.0)),  # 0
                    (
                        (-1, self.ground_level, -maze.shape[1] - 1),
                        (0.0, gravel_scale * (maze.shape[1] + 2)),
                    ),  # 1
                    (
                        (maze.shape[0] + 1, self.ground_level,
                         -maze.shape[1] - 1),
                        (
                            gravel_scale * (maze.shape[0] + 2),
                            gravel_scale * (maze.shape[1] + 2),
                        ),
                    ),  # 2
                    (
                        (maze.shape[0] + 1, self.ground_level, 0.0),
                        (gravel_scale * (maze.shape[0] + 2), 0.0),
                    ),
                ],  # 3
                dtype=[("position", np.float32, 3),
                       ("texture", np.float32, 2)],
            ),
            np.array([0, 1, 2, 3], dtype=np.uint32),
            gl.GL_QUADS,
            "gravel.jpg",
        )
        self.walls = None
        self.egress = None

        self.program = GLProgram(
            (GLShader.from_file(*args) for args in (
                (gl.GL_VERTEX_SHADER, "tunnel_view.vert.glsl"),
                (gl.GL_FRAGMENT_SHADER, "tunnel_view.frag.glsl"),
            )),
            do_use=True,
        )

        # Uniform
        self.transform_loc = gl.glGetUniformLocation(self.program.gl_id,
                                                     b"transform")

        self.cummulative_time = 0.0
Ejemplo n.º 24
0
    def uniform(self, name, type, count=1):

        if name not in self.__uniforms:

            location = gl.glGetUniformLocation(
                self.__program, name)

            self.__uniforms[name] = Uniform(
                self.__program, location, type, count)

        return self.__uniforms[name]
Ejemplo n.º 25
0
 def uniformf(self, name, *vals):
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         # select the correct function
         {
             1: glUniform1f,
             2: glUniform2f,
             3: glUniform3f,
             4: glUniform4f
         # retrieve the uniform location, and set
         }[len(vals)](glGetUniformLocation(self.handle, name), *vals)
Ejemplo n.º 26
0
 def uniformi(self, name, *vals):
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         # select the correct function
         { 1 : GL.glUniform1i,
           2 : GL.glUniform2i,
           3 : GL.glUniform3i,
           4 : GL.glUniform4i
           # retrieve the uniform location, and set
         }[len(vals)](GL.glGetUniformLocation(self.handle, 
                                              name.encode("ascii")), *vals)            
Ejemplo n.º 27
0
 def uniformi(self, name, *vals):
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         # select the correct function
         {
             1: GL.glUniform1i,
             2: GL.glUniform2i,
             3: GL.glUniform3i,
             4: GL.glUniform4i
             # retrieve the uniform location, and set
         }[len(vals)](GL.glGetUniformLocation(self.handle,
                                              name.encode("ascii")), *vals)
Ejemplo n.º 28
0
 def uniformi(self, name: str, *vals):
     # upload an integer uniform
     # this program must be currently bound
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         vals = list(map(c_int, vals))
         # select the correct function
         location = glGetUniformLocation(
             self.handle, c_char_p(name.encode("utf-8")))
         uniform_functions = {1: glUniform1i,
                              2: glUniform2i, 3: glUniform3i, 4: glUniform4i}
         uniform_functions[len(vals)](location, *vals)
Ejemplo n.º 29
0
 def uniformf(self, name: str, *vals):
     # upload a floating point uniform
     # this program must be currently bound
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         vals = list(map(c_float, vals))
         location = glGetUniformLocation(
             self.handle, c_char_p(name.encode("utf-8")))
         # select the correct function
         uniform_functions = {1: glUniform1f,
                              2: glUniform2f, 3: glUniform3f, 4: glUniform4f}
         uniform_functions[len(vals)](location, *vals)
Ejemplo n.º 30
0
    def __init__(self,
                 vertex_shader: Shader,
                 fragment_shader: Shader,
                 attributes=(),
                 uniforms=None):
        """
        The process of creating a shader can be divided into 6 steps:

            1. Create an ID.
            2. Attach shaders.
            3. Bind attributes.
            4. Link program.
            5. Validate program.
            6. Bind uniforms.

        Args:
            vertex_shader:
            fragment_shader:
            attributes:
            uniforms:  A dictionary with the names of the uniform as the key, and the uniform (glsl value) as value.
        """

        if uniforms is None:
            uniforms = {}

        handle = -1
        attribute_location = {}
        uniform_location = {}

        try:
            handle = glCreateProgram()
            glAttachShader(handle, vertex_shader)
            glAttachShader(handle, fragment_shader)
            for index, name in enumerate(attributes):
                glBindAttribLocation(handle, index, c_string(name))
                attribute_location[name] = index
            glLinkProgram(handle)
            glValidateProgram(handle)
            for uniform in uniforms:
                uniform_location[uniform] = glGetUniformLocation(
                    handle, c_string(uniform))
        except GLException:
            debug_program(handle)

        super(Program, self).__init__(handle)
        self.vertex_shader = vertex_shader
        self.fragment_shader = fragment_shader
        self.attribute_location = attribute_location
        self.uniform_location = uniform_location
        self.uniforms = uniforms

        if CHECK_ERROR:
            debug_program(self)
Ejemplo n.º 31
0
 def set_uniform(self, name, value):
     name = name.encode()
     valtype = type(value)
     if valtype == bool or valtype == int:
         glUniform1i(glGetUniformLocation(self.shader, name), int(value))
     elif valtype == float:
         glUniform1f(glGetUniformLocation(self.shader, name), value)
     # elif valtype == VECTOR2_TYPE:
     #     glUniform2fv(glGetUniformLocation(self.shader, name), 1, value)
     elif valtype == VECTOR3_TYPE:
         glUniform3fv(glGetUniformLocation(self.shader, name), 1,
                      c_float(value[0]), c_float(value[1]),
                      c_float(value[2]))
     elif valtype == VECTOR4_TYPE:
         glUniform4fv(glGetUniformLocation(self.shader, name), 1,
                      c_float(value[0]), c_float(value[1]),
                      c_float(value[2]), c_float(value[3]))
     elif valtype == MATRIX3_TYPE:
         glUniformMatrix3fv(
             glGetUniformLocation(self.shader, name), 1, GL_FALSE,
             c_float(value[0][0]))  # Should this be value[0][0]?
     elif valtype == MATRIX4_TYPE:
         glUniformMatrix4fv(
             glGetUniformLocation(self.shader, name), 1, GL_FALSE,
             c_float(value[0][0]))  # Should this be value[0][0]?
Ejemplo n.º 32
0
def render_to_texture(in_size, out_size, view_z=None):
    z0, z1 = (0, in_size[2]) if view_z == None else view_z
    vertices = (VERTEX * 6)(((-1, -1), (0, 0)), ((1, -1), (1, 0)),
                            ((1, 1), (1, 1)), ((1, 1), (1, 1)),
                            ((-1, 1), (0, 1)), ((-1, -1), (0, 0)))
    gl.glBindTexture(gl.GL_TEXTURE_3D, rendered_texture)
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer)
    draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
    gl.glDrawBuffers(1, draw_buffers)
    gl.glViewport(0, 0, out_size[0], out_size[1])
    gl.glUseProgram(render_program)
    loc_depth = gl.glGetUniformLocation(render_program,
                                        ctypes.create_string_buffer(b'depth'))
    loc_texelSize = gl.glGetUniformLocation(
        render_program, ctypes.create_string_buffer(b'texelSize'))
    gl.glUniform3f(loc_texelSize, 1 / in_size[0], 1 / in_size[1],
                   1 / in_size[2])
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(vertices), vertices,
                    gl.GL_DYNAMIC_DRAW)
    gl.glBindVertexArray(render_vao)
    gl.glClearColor(0.0, 0.0, 0.0, 0.0)
    for z in range(out_size[2]):
        gl.glFramebufferTexture3D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0,
                                  gl.GL_TEXTURE_3D, rendered_texture, 0, z)
        fbs = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER)
        assert fbs == gl.GL_FRAMEBUFFER_COMPLETE, 'FramebufferStatus is {}'.format(
            fbs)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        gl.glUniform1f(loc_depth,
                       (z0 + z * (z1 - z0)) / in_size[2] / out_size[2])
        gl.glBindTexture(gl.GL_TEXTURE_3D, input_texture)
        gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
        if z % 10 == 0:
            gl.glFinish()
            print('\033[K{}/{}'.format(z, out_size[2] - 1), end='\r')
    gl.glFinish()

    gl.glBindVertexArray(0)
Ejemplo n.º 33
0
    def add_uniform(self, uname, dtype):
        """Add a uniform to the shader program.

        :param uname: name of the uniform.
        :type uname: str

        :param dtype: data type of the uniform -- 'vec3', 'mat4', etc
        :type dtype: str

        """
        ufunc = uniform_function_map[dtype]
        loc = gl.glGetUniformLocation(self._pid, uname.encode())
        self._uniforms[uname] = Uniform(uname, loc, ufunc)
Ejemplo n.º 34
0
 def uniformf(self, name: str, *vals):
     # upload a floating point uniform
     # this program must be currently bound
     # check there are 1-4 values
     if len(vals) in range(1, 5):
         c_vals = list(map(c_float, vals))
         location = glGetUniformLocation(self.handle, bytes(name, "utf-8"))
         uniform_functions = {
             1: glUniform1f,
             2: glUniform2f,
             3: glUniform3f,
             4: glUniform4f
         }
         uniform_functions[len(c_vals)](location, *c_vals)
Ejemplo n.º 35
0
    def uniformf(self, name, *vals):
        ''' Uploads float uniform(s), program must be currently bound. '''

        loc = self.uniforms.get(name,
                                gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc

        # Check there are 1-4 values
        if len(vals) in range(1, 5):
            # Select the correct function
            { 1 : gl.glUniform1f,
              2 : gl.glUniform2f,
              3 : gl.glUniform3f,
              4 : gl.glUniform4f
              # Retrieve uniform location, and set it
            }[len(vals)](loc, *vals)
Ejemplo n.º 36
0
    def uniformi(self, name, *vals):
        ''' Upload integer uniform(s), program must be currently bound. '''

        loc = self.uniforms.get(name,
                                gl.glGetUniformLocation(self.handle,name))
        self.uniforms[name] = loc

        # Checks there are 1-4 values
        if len(vals) in range(1, 5):
            # Selects the correct function
            { 1 : gl.glUniform1i,
              2 : gl.glUniform2i,
              3 : gl.glUniform3i,
              4 : gl.glUniform4i
              # Retrieves uniform location, and set it
            }[len(vals)](loc, *vals)
Ejemplo n.º 37
0
 def setInt(self, name, value):
     if type(name) is not bytes:
         name = bytes(name, 'utf-8')
     loc = GL.glGetUniformLocation(self.handle, name)
     if not hasattr(value, '__len__'):
         GL.glUniform1i(loc, value)
     elif len(value) in range(1, 5):
         # Select the correct function
         { 1 : GL.glUniform1i,
           2 : GL.glUniform2i,
           3 : GL.glUniform3i,
           4 : GL.glUniform4i
           # Retrieve uniform location, and set it
         }[len(value)](loc, value)
     else:
         raise ValueError("Shader.setInt '{}' should be length 1-4 not {}"
                          .format(name, len(value)))
Ejemplo n.º 38
0
    def send(self):
        """
        Sends all the key-value pairs to the graphics card.
        These uniform variables will be available in the currently-bound shader.
        """

        for name, array in iteritems(self):

            shader_id = c_int(0)
            gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(shader_id))
            if shader_id.value == 0:
                raise UnboundLocalError(
                    """Shader not bound to OpenGL context--uniform cannot be sent.
                ------------ Tip -------------
                with ratcave.default_shader:
                    mesh.draw()
                ------------------------------
                """)

            # Attach a shader location value to the array, for quick memory lookup. (gl calls are expensive, for some reason)
            try:
                loc, shader_id_for_array = array.loc
                if shader_id.value != shader_id_for_array:
                    raise Exception(
                        'Uniform location bound to a different shader')
            except (AttributeError, Exception) as e:
                array.loc = (gl.glGetUniformLocation(shader_id.value,
                                                     name.encode('ascii')),
                             shader_id.value)

            if array.ndim == 2:  # Assuming a 4x4 float32 matrix (common for graphics operations)
                try:
                    pointer = array.pointer
                except AttributeError:
                    array.pointer = array.ctypes.data_as(POINTER(c_float *
                                                                 16)).contents
                    pointer = array.pointer
                gl.glUniformMatrix4fv(array.loc[0], 1, True, pointer)

            else:
                sendfun = self._sendfuns[array.dtype.kind][
                    len(array) - 1]  # Find correct glUniform function
                sendfun(array.loc[0], *array)
Ejemplo n.º 39
0
    def _uniform_loc_storage_and_type(self, var):
        """Return the uniform location and a container that can
        store its value.

        Parameters
        ----------
        var : string
            Uniform name.

        """
        if var not in self.active_uniforms:
            raise GLSLError("Uniform '%s' is not active.  Make sure the "
                            "variable is used in the source code." % var)

        try:
            var_info = self._uniform_type_info[var]
        except KeyError:
            raise ValueError("Uniform variable '%s' is not defined in "
                             "shader source." % var)

        # If this is an array, how many values are involved?
        count = var_info['array']

        if var_info['kind'] in ['int']:
            data_type = gl.GLint
        else:
            data_type = gl.GLfloat

        assert gl.glIsProgram(self.handle) == True
        assert self.linked

        loc = gl.glGetUniformLocation(self.handle, var)

        if loc == -1:
            raise RuntimeError("Could not query uniform location "
                               "for '%s'." % var)

        storage = data_type * (count * var_info['size'])
        storage_nested = count * (data_type * var_info['size'])

        return loc, storage, storage_nested, data_type
Ejemplo n.º 40
0
    def __setitem__(self, uniform, value):
        try:
            uid = self.uniforms[uniform]
        except KeyError:
            uid = gl.glGetUniformLocation(self.program, uniform)
            if uid == -1:
                raise NoSuchUniformError(uniform)
            self.uniforms[uniform] = uid

        args = [uid]
        if isinstance(value, (int, ctypes.c_int)):
            setter = gl.glUniform1i
            args.append(value)
        elif isinstance(value, (float, ctypes.c_float, ctypes.c_double)):
            setter = gl.glUniform1f
            args.append(value)
        else:
            args.extend(value)
            setter = SETTERSF[len(args) - 2]

        setter(*args)
Ejemplo n.º 41
0
    def _introspect_uniforms(self):
        """Figure out what uniforms are available and build an internal map"""
        # Number of active uniforms in the program
        active_uniforms = gl.GLint(0)
        gl.glGetProgramiv(self._glo, gl.GL_ACTIVE_UNIFORMS,
                          byref(active_uniforms))

        # Loop all the active uniforms
        for index in range(active_uniforms.value):
            # Query uniform information like name, type, size etc.
            u_name, u_type, u_size = self._query_uniform(index)
            u_location = gl.glGetUniformLocation(self._glo, u_name.encode())

            # Skip uniforms that may be in Uniform Blocks
            # TODO: We should handle all uniforms
            if u_location == -1:
                # print(f"Uniform {u_location} {u_name} {u_size} {u_type} skipped")
                continue

            u_name = u_name.replace("[0]", "")  # Remove array suffix
            self._uniforms[u_name] = Uniform(self._glo, u_location, u_name,
                                             u_type, u_size)
Ejemplo n.º 42
0
    def __getitem__(self, var):
        """Get uniform value.

        """
        loc, container, container_nested, dtype = \
             self._uniform_loc_storage_and_type(var)
        var_info = self._uniform_type_info[var]
        data = container_nested()

        if dtype == gl.GLint:
            get_func = gl.glGetUniformiv
        else:
            get_func = gl.glGetUniformfv

        alen = var_info['array']
        for i in range(alen):
            if i > 0:
                # Query the location of each array element
                loc = gl.glGetUniformLocation(self.handle, var + '[%d]' % i)

            assert loc != -1

            get_func(self.handle, loc, data[i])

        # Convert to a NumPy array for easier processing
        data = np.array(data)

        # Scalar
        if data.size == 1:
            return data[0]
        # Array, matrix, vector
        elif var_info['kind'] == 'mat':
            count, n_sqr = data.shape
            n = np.sqrt(n_sqr)

            data = data.reshape((count, n, n), order='F')

        return data
Ejemplo n.º 43
0
 def set_uniform_f(self, name, value):
     location = gl.glGetUniformLocation(self.program, name)
     gl.glUniform1f(location, value)
Ejemplo n.º 44
0
 def get_uniform_location(self, name):
     return gl.glGetUniformLocation(self.id, name.encode('ascii'))
Ejemplo n.º 45
0
 def set_uniform_matrix(self, name, mat):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     gl.glUniformMatrix4fv(location, 1, False, (ct.c_float * 16)(*mat))
Ejemplo n.º 46
0
 def set_uniform_f(self, name, value):
     location = gl.glGetUniformLocation(self.program, name)
     gl.glUniform1f(location, value)
Ejemplo n.º 47
0
 def set_uniform_matrix(self, name, mat):
     location = gl.glGetUniformLocation(self.program, name.encode('ascii'))
     gl.glUniformMatrix4fv(location, 1, False, (ct.c_float * 16)(*mat))
Ejemplo n.º 48
0
 def uniform_matrixf(self, name, mat):
     # obtian the uniform location
     loc = GL.glGetUniformLocation(self.Handle, name)
     # uplaod the 4x4 floating point matrix
     GL.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))
     
Ejemplo n.º 49
0
        def __init__(self, frames):
            #consider bumping opengl version if apple supports it
            #amdgpu-mesa currently supports up to 4.5
            super(ControledRender,
                  self).__init__(512,
                                 512,
                                 fullscreen=False,
                                 config=gl.Config(major_version=4,
                                                  minor_version=1),
                                 visible=False)
            print(self.context.get_info().get_version())

            self.frames = frames
            self.vertex_buffer = gl.GLuint(0)
            self.vao = gl.GLuint(0)
            #self.prev_program = (gl.GLint * 1)()

            self.dimx = args["A"].shape[0]
            self.dimy = args["A"].shape[1]

            A = args["A"].astype(np.float32)
            #print("A shape " + str(A.shape))
            #print(str(A.dtype))
            #print(A)

            B = args["B"].astype(np.float32)

            #self.dp = self.tdata.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p))
            self.Ap = A.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p))
            self.Bp = B.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p))

            self.setupFBOandTextures()

            self.setupShaders()

            data = [
                -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
                1.0
            ]

            dataGl = (gl.GLfloat * len(data))(*data)

            gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer))
            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer)
            gl.glBufferData(gl.GL_ARRAY_BUFFER,
                            len(dataGl) * 4, dataGl, gl.GL_STATIC_DRAW)

            gl.glGenVertexArrays(1, ctypes.byref(self.vao))
            gl.glBindVertexArray(self.vao)
            gl.glUseProgram(self.programA)
            self.pos_posA = gl.glGetAttribLocation(
                self.programA, ctypes.create_string_buffer(b"a_position"))
            assert (self.pos_posA >= 0)
            gl.glEnableVertexAttribArray(self.pos_posA)
            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer)
            gl.glVertexAttribPointer(self.pos_posA, 2, gl.GL_FLOAT, False, 0,
                                     0)

            self.tex_pos_A_A = gl.glGetUniformLocation(self.programA, b"A")
            self.tex_pos_A_B = gl.glGetUniformLocation(self.programA, b"B")
            self.feed_pos_A = gl.glGetUniformLocation(self.programA, b"f")
            self.kill_pos_A = gl.glGetUniformLocation(self.programA, b"k")
            self.dA_pos_A = gl.glGetUniformLocation(self.programA, b"dA")
            self.dB_pos_A = gl.glGetUniformLocation(self.programA, b"dB")
            self.dt_pos_A = gl.glGetUniformLocation(self.programA, b"timestep")
            self.step_pos_A = gl.glGetUniformLocation(self.programA, b"step")
            gl.glUniform1f(self.feed_pos_A, args["feed"])
            gl.glUniform1f(self.kill_pos_A, args["kill"])
            gl.glUniform1f(self.dA_pos_A, args["dA"])
            gl.glUniform1f(self.dB_pos_A, args["dB"])
            gl.glUniform1f(self.dt_pos_A, args["dt"])
            #may need changed for nonsquare textures
            gl.glUniform1f(self.step_pos_A, 1 / self.dimx)

            gl.glUseProgram(self.programB)
            self.pos_posB = gl.glGetAttribLocation(
                self.programB, ctypes.create_string_buffer(b"a_position"))
            assert (self.pos_posB >= 0)
            gl.glEnableVertexAttribArray(self.pos_posB)
            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer)
            gl.glVertexAttribPointer(self.pos_posB, 2, gl.GL_FLOAT, False, 0,
                                     0)

            self.tex_pos_B_A = gl.glGetUniformLocation(self.programB, b"A")
            self.tex_pos_B_B = gl.glGetUniformLocation(self.programB, b"B")
            self.feed_pos_B = gl.glGetUniformLocation(self.programB, b"f")
            self.kill_pos_B = gl.glGetUniformLocation(self.programB, b"k")
            self.dA_pos_B = gl.glGetUniformLocation(self.programB, b"dA")
            self.dB_pos_B = gl.glGetUniformLocation(self.programB, b"dB")
            self.dt_pos_B = gl.glGetUniformLocation(self.programB, b"timestep")
            self.step_pos_B = gl.glGetUniformLocation(self.programB, b"step")
            gl.glUniform1f(self.feed_pos_B, args["feed"])
            gl.glUniform1f(self.kill_pos_B, args["kill"])
            gl.glUniform1f(self.dA_pos_B, args["dA"])
            gl.glUniform1f(self.dB_pos_B, args["dB"])
            gl.glUniform1f(self.dt_pos_B, args["dt"])
            #may need changed for nonsquare textures
            gl.glUniform1f(self.step_pos_B, 1 / self.dimx)

            gl.glViewport(0, 0, self.dimx, self.dimy)
Ejemplo n.º 50
0
  def __set_uniforms(self):
    # projection matrix (proj)
    proj_loc = gl.glGetUniformLocation(self.__prog.value, "proj")
    proj_matrix = self.__proj_matrix()
    proj_matrix_ptr = ct.cast( \
        ct.pointer(np.ctypeslib.as_ctypes(proj_matrix)),
        ct.POINTER(ct.c_float) )
    gl.glUniformMatrix4fv(proj_loc, 1, gl.GL_TRUE, 
        proj_matrix_ptr)

    # voxel spacing
    voxel_spacing_loc = gl.glGetUniformLocation(self.__prog.value,
        "voxel_spacing")
    gl.glUniform3f(voxel_spacing_loc,
        self.__voxel_spacing[0]*self.__downsample,
        self.__voxel_spacing[1]*self.__downsample,
        self.__voxel_spacing[2]*self.__downsample)

    # voxel size
    voxel_size_loc = gl.glGetUniformLocation(self.__prog.value,
        "voxel_size")
    gl.glUniform3f(voxel_size_loc,
        self.__voxel_size[0]*self.__downsample,
        self.__voxel_size[1]*self.__downsample,
        self.__voxel_size[2]*self.__downsample)

    # data; not technically a "uniform" but a texture
    data_loc = gl.glGetUniformLocation(self.__prog.value,
        "data")
    gl.glUniform1i(data_loc, 0)

    gl.glActiveTexture(gl.GL_TEXTURE0)
    gl.glBindTexture(gl.GL_TEXTURE_BUFFER, self.__data_texture.value)

    # dims
    dims_loc = gl.glGetUniformLocation(self.__prog.value,
        "dims")
    gl.glUniform3i(dims_loc,
        self.__data.shape[0]/self.__downsample,
        self.__data.shape[1]/self.__downsample,
        self.__data.shape[2]/self.__downsample)

    # global_opacity
    global_opacity_loc = gl.glGetUniformLocation(self.__prog.value,
        "global_opacity")
    gl.glUniform1f(global_opacity_loc, self.__opacity)

    # min value
    min_value_loc = gl.glGetUniformLocation(self.__prog.value,
        "min_value")
    gl.glUniform1f(min_value_loc, self.__min_value)

    # saturation value
    saturation_value_loc = gl.glGetUniformLocation(self.__prog.value,
        "saturation_value")
    gl.glUniform1f(saturation_value_loc, self.__saturation_value)

    # downsample
    downsample_loc = gl.glGetUniformLocation(self.__prog.value,
        "downsample")
    gl.glUniform1i(downsample_loc, self.__downsample)