Beispiel #1
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]?
Beispiel #2
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)
Beispiel #3
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))
Beispiel #4
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)
Beispiel #5
0
    def draw(self,
             uniforms,
             entity,
             models,
             textures=(),
             color=(1.0, 1.0, 1.0),
             *args,
             **kwargs):
        glUseProgram(self)
        glDisable(GL_DEPTH_TEST)

        # Draw objects once as invisible to set stencil values.
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE,
                    GL_FALSE)  # Don't write any color values to color buffer.
        glStencilMask(0xFF)  # Enable writing.

        model = models[entity.model]

        model.positions.enable()
        model.indices.enable()

        self.uniforms[b'perspective'].load(
            uniforms.get(b'perspective').ctypes.data_as(POINTER(GLfloat)))
        self.uniforms[b'view'].load(
            uniforms.get(b'view').ctypes.data_as(POINTER(GLfloat)))
        self.uniforms[b'color'].load(*color)

        entity.get_transformation_matrix(
            location=self.uniforms[b'transformation'])

        model.draw()

        # Draw again with larger model.
        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)

        glStencilFunc(GL_NOTEQUAL, 1,
                      0xFF)  # Update with 1's where the objects are rendered.
        glStencilMask(
            0x00
        )  # Value that AND's the value written to buffer. 0x00 basically disables writing to stencil.

        glUniformMatrix4fv(
            self.uniforms[b'transformation'], 1, GL_TRUE,
            create_transformation_matrix(
                *entity._location, *entity.rotation,
                *(entity.scale + 0.05)).ctypes.data_as(POINTER(GLfloat)))

        model.draw()

        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

        glDisableVertexAttribArray(0)

        glEnable(GL_DEPTH_TEST)
        glStencilMask(0xFF)
Beispiel #6
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)
Beispiel #7
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)
Beispiel #8
0
 def _draw_mouse_cursor(self):
     """ If the mouse is over the image, draw a cursom crosshair. """
     if self.mouse_position is None:
         return
     x, y = self.mouse_position
     w, h = self.get_size()
     vm = self._make_cursor_view_matrix(x, y)
     with self.mouse_texture:
         gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
         gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*vm))
         gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
         gl.glBlendFunc(gl.GL_ONE, gl.GL_ZERO)
Beispiel #9
0
 def _draw_mouse_cursor(self):
     """ If the mouse is over the image, draw a cursor crosshair. """
     if self.mouse_position is None:
         return
     x, y = self.mouse_position
     tw, th = self.mouse_texture.size
     gl.glViewport(x - tw, y - th - 1, tw * 2 + 1, th * 2 + 1)
     with self.vao, self.copy_program:
         with self.mouse_texture:
             gl.glEnable(gl.GL_BLEND)
             gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
             gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, EYE4)
             gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
             gl.glBlendFunc(gl.GL_ONE, gl.GL_ZERO)
     ww, wh = self.get_pixel_aligned_size()
     gl.glViewport(0, 0, int(ww), int(wh))
Beispiel #10
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)
Beispiel #11
0
    def draw(self, uniforms, entities, models, textures=(), lights=(), *args, **kwargs):
        glUseProgram(self)

        # PREPARE SHADER
        glUniformMatrix4fv(  # ctypes.data_as must be here and not at initialization.
            self.uniforms[b'perspective'], 1, GL_TRUE, uniforms.get(b'perspective').ctypes.data_as(POINTER(GLfloat))
        )
        glUniformMatrix4fv(
            self.uniforms[b'view'], 1, GL_TRUE, uniforms.get(b'view').ctypes.data_as(POINTER(GLfloat))
        )

        for i, entity in enumerate(lights):
            glUniform3f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].position'],  *entity.location)
            glUniform3f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].color'],     *entity.color)
            glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].constant'],  entity.attenuation[0])
            glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].linear'],    entity.attenuation[1])
            glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].quadratic'], entity.attenuation[1])


        # PREPARE MODELS
        for model_index, texture_mapping in self.entities.items():

            model = models[model_index]
            model.enable()

            # PREPARE TEXTURES
            glActiveTexture(GL_TEXTURE0)
            glActiveTexture(GL_TEXTURE0 + 1)
            for texture_list, entity_list in texture_mapping.items():

                if hasattr(texture_list, '__iter__'):
                    glBindTexture(GL_TEXTURE_2D, textures[0])
                    glUniform1i(self.uniforms[b'diffuse_texture'], 0)
                    glBindTexture(GL_TEXTURE_2D, textures[1])
                    glUniform1i(self.uniforms[b'specular_texture'], 1)

                    # textures[0].enable(slot=0)
                    # textures[1].enable(slot=1)

                else:
                    textures[texture_list].enable(slot=0)
                    glUniform1i(self.uniforms[b'diffuse_texture'], 0)


                # PREPARE ENTITIES
                for entity in entity_list:
                    glUniformMatrix4fv(
                        self.uniforms[b'transformation'], 1, GL_TRUE,
                        entity.get_transformation_matrix().ctypes.data_as(POINTER(GLfloat))
                    )
                    model.draw()

        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

        glBindTexture(GL_TEXTURE_2D, 0)

        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
        glDisableVertexAttribArray(2)
Beispiel #12
0
    def draw(self, uniforms, entities, models, *args, **kwargs):
        glUseProgram(self)

        glUniformMatrix4fv(
            self.uniforms[b'perspective'], 1, GL_TRUE, uniforms.get(b'perspective').ctypes.data_as(POINTER(GLfloat))
        )
        glUniformMatrix4fv(
            self.uniforms[b'view'], 1, GL_TRUE, uniforms.get(b'view').ctypes.data_as(POINTER(GLfloat))
        )

        for model_index, entity_list in entities.items():
            model = models[model_index]

            model.enable()

            for entity in entity_list:
                glUniformMatrix4fv(
                    self.uniforms[b'transformation'], 1, GL_TRUE,
                    entity.get_transformation_matrix().ctypes.data_as(POINTER(GLfloat))
                )
                glUniform3f(self.uniforms[b'color'], *entity.color)

                model.draw()

        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

        glBindTexture(GL_TEXTURE_2D, 0)


        glDisableVertexAttribArray(0)
Beispiel #13
0
    def _render_view(self):

        gl.glClearBufferfv(gl.GL_COLOR, 0, (gl.GLfloat * 4)(0.25, 0.25, 0.25,
                                                            1))

        if not self.view:
            return

        w, h, d = self.view.shape
        size = w, h
        window_size = self.get_size()

        ob = render_view(self)

        vm = make_view_matrix(window_size, size, self.zoom, self.offset)
        vm = (gl.GLfloat * 16)(*vm)
        gl.glViewport(0, 0, *window_size)

        self._update_border(self.view.shape)
        with self.border_vao, self.line_program:
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, vm)
            r, g, b, a = self.drawing.palette.colors[
                0]  # Color 0 is currently hardcoded background
            gl.glUniform3f(1, r / 256, g / 256, b / 256)
            gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, 4)

        with self.vao, self.copy_program:
            # Draw the actual drawing
            with ob["color"]:
                gl.glEnable(gl.GL_BLEND)
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      (gl.GLfloat * 16)(*vm))
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
            self._draw_mouse_cursor()

        with self.border_vao, self.line_program:
            gl.glUniform3f(1, 0., 0., 0.)
            gl.glLineWidth(1)
            gl.glDrawArrays(gl.GL_LINE_LOOP, 0, 4)
Beispiel #14
0
    def render(self, position, chunk_meshes):

        gl.glViewport(0, 0, *self.size)
        gl.glDisable(gl.GL_BLEND)
        gl.glDisable(gl.GL_ALPHA_TEST)
        gl.glEnable(gl.GL_CULL_FACE)

        gl.glEnable(gl.GL_DEPTH_TEST)
        gl.glDepthFunc(gl.GL_LEQUAL)
        gl.glDepthMask(gl.GL_TRUE)

        x, y, z = position

        view_matrices = [
            Matrix4.new_scale(-1, -1, 1).rotatey(pi / 2).translate(-x, -y,
                                                                   -z),  # +X
            Matrix4.new_scale(-1, -1,
                              1).rotatey(-pi / 2).translate(-x, -y, -z),  # -X
            Matrix4.new_rotatex(-pi / 2).translate(-x, -y, -z),  # +Y
            Matrix4.new_rotatex(pi / 2).translate(-x, -y, -z),  # -Y
            Matrix4.new_scale(-1, -1, 1).rotatey(pi).translate(-x, -y,
                                                               -z),  # +Z
            Matrix4.new_scale(-1, -1, 1).translate(-x, -y, -z)  # -Z
        ]

        model_matrix = Matrix4.new_scale(
            1, 1, constants.WALL_TEXTURE_HEIGHT /
            (constants.WALL_TEXTURE_WIDTH / sqrt(2) * (sqrt(3))))
        gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE, gl_matrix(model_matrix))
        with self.program, self.name:

            view_matrix = make_view_matrix_persp(position)
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, gl_matrix(view_matrix))

            for chunk, mesh in chunk_meshes.items():
                mesh.draw()
Beispiel #15
0
    def display_update(self):
        assert self.player is not None
        self.switch_to()

        if self.walls is None:
            self.build_walls()

        # view
        if self.cummulative_time >= self.target_time:
            pc = self.target_camera
        else:
            pc = self.target_camera - self.delta_camera * (
                max(self.target_time - self.cummulative_time, 0.0) /
                self.delta_time)

        camera = pyrr.vector3.create(
            pc[0] + 0.5,
            (self.ground_level + self.wall_level) / 2.0,
            -pc[1] - 0.5,
            dtype=np.float32,
        )
        direction = pyrr.vector3.create(-np.sin(pc[2]), 0.0, np.cos(pc[2]))
        view = look_at(camera, direction=direction)
        transform = view

        # then project
        projection = pyrr.matrix44.create_perspective_projection_matrix(
            90.0, self.width / self.height, 0.1, 1000.0, dtype=np.float32).T
        transform = np.dot(projection, transform)

        gl.glUniformMatrix4fv(
            self.transform_loc,  # location
            1,  # count
            gl.GL_TRUE,  # Numpy uses Row-Dominant, OpenGL used Column-Dominant
            (gl.GLfloat * transform.size)(*transform.flatten()),
        )  # value
Beispiel #16
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)
Beispiel #17
0
 def uniform_matrix(
         self, location,
         matrix):  # pass a matrix to the specified location in the program
     gl.glUniformMatrix4fv(location, 1, gl.GL_FALSE,
                           (gl.GLfloat * 16)(*sum(matrix.data, [])))
Beispiel #18
0
def render_view(window):
    """ Render the current view to a texture. """

    drawing = window.drawing
    view = window.view

    changed = False

    # Update the overlay with the current stroke
    overlay = view.overlay
    w, h, d = view.shape
    size = w, h
    overlay_texture = _get_overlay_texture(size)
    if overlay.dirty and overlay.lock.acquire(timeout=0.01):
        rect = overlay.dirty
        x0, y0, x1, y1 = rect.box()
        overlay_data = overlay.data[x0:x1, y0:y1].tobytes("F")
        gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT,
                         1)  # Needed for writing 8bit data
        gl.glTextureSubImage2D(overlay_texture.name, 0, *rect.position,
                               *rect.size, gl.GL_RGBA_INTEGER,
                               gl.GL_UNSIGNED_BYTE, overlay_data)
        gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4)
        overlay.dirty = None
        overlay.lock.release()
        changed = True

    # Update the image texture
    data = drawing.data
    drawing_texture = _get_3d_texture(data.shape)
    if drawing.dirty:
        with drawing.lock:
            update_data = data[drawing.dirty].tobytes(order="F")
            sx, sy, sz = drawing.dirty
            drawing.dirty = None
        sw = sx.stop - sx.start
        sh = sy.stop - sy.start
        sd = sz.stop - sz.start
        gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT,
                         1)  # Needed for writing 8bit data
        gl.glTextureSubImage3D(drawing_texture.name, 0, sx.start, sy.start,
                               sz.start, sw, sh, sd, gl.GL_RED_INTEGER,
                               gl.GL_UNSIGNED_BYTE, update_data)
        gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4)
        changed = True

    # Render everything to the offscreen buffer

    # TODO we actually should not have to redraw the offscreen_buffer unless something has changed
    # (e.g. drawing, overlay, palette or cursor)

    offscreen_buffer = _get_offscreen_buffer(size)
    colors = _get_colors(drawing.palette.colors)

    vao = _get_vao()
    draw_program = _get_program()
    empty_texture = _get_empty_texture(size)

    cursor_pos = d - view.index - 1  # TODO why?

    other_layer_alpha = 0.3 if view.show_only_current_layer or view.layer_being_switched else 1.0

    T = _get_transform(view.rotation)

    with vao, offscreen_buffer:

        gl.glEnable(gl.GL_BLEND)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        gl.glViewport(0, 0, w, h)
        gl.glClearBufferfv(gl.GL_COLOR, 0, EMPTY_COLOR)

        with draw_program, drawing_texture:

            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*T))
            gl.glUniform3f(1, *view.direction)
            gl.glUniform4fv(5, 256, colors)

            # Draw the layers below the current one
            if cursor_pos < d - 1:
                with empty_texture:
                    gl.glUniform1f(2, other_layer_alpha)
                    gl.glUniform2i(3, cursor_pos + 1, d)
                    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

            # Draw the current layer + overlay
            with overlay_texture:
                gl.glUniform1f(2, 1)
                gl.glUniform2i(3, cursor_pos, cursor_pos + 1)
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

            # Draw the layers on top
            if cursor_pos > 0:
                with empty_texture:
                    gl.glUniform1f(2, other_layer_alpha)
                    gl.glUniform2i(3, 0, cursor_pos)
                    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

    return offscreen_buffer
Beispiel #19
0
    def load_uniform_matrix(self, **uniforms):
        self._assert_bound()

        for name, data in uniforms.items():
            glUniformMatrix4fv(self.uniform[name], 1, GL_TRUE,
                               data.ctypes.data_as(POINTER(GLfloat)))
Beispiel #20
0
    def __call__(self, oldpaint, imgui, drawing, brush,
                 altitude: float=-120, azimuth: float=0, spin: bool=False):
        selection = drawing.selection
        if selection:
            size = selection.size
            depth = len(drawing.layers)
            colors = drawing.palette.as_tuple()

            mesh = self._get_mesh(tuple(drawing.layers), selection, colors)
            if not mesh:
                # TODO hacky
                self.texture and self.texture[0].clear()
                return

            w, h = size
            model_matrix = Matrix4.new_translate(-w/2, -h/2, depth/2).scale(1, 1, 1/math.sin(math.pi/3))

            far = w*2
            near = 0
            frust = Matrix4()
            frust[:] = (2/w, 0, 0, 0,
                        0, 2/h, 0, 0,
                        0, 0, -2/(far-near), 0,
                        0, 0, -(far+near)/(far-near), 1)
            
            offscreen_buffer = self._get_buffer(size)
            with offscreen_buffer, self.program, \
                    enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

                azimuth = math.degrees(time()) if spin else azimuth
                view_matrix = (
                    Matrix4
                    # .new_scale(2/w, 2/h, 1/max(w, h))
                    .new_translate(0, 0, -w)
                    .rotatex(math.radians(altitude))
                    .rotatez(math.radians(azimuth))  # Rotate over time
                )
                
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      gl_matrix(frust * view_matrix * model_matrix))

                gl.glViewport(0, 0, *size)
                gl.glPointSize(1.0)

                mesh.draw(mode=gl.GL_POINTS)

            shadow_buffer = self._get_shadow_buffer(size)                
            with shadow_buffer, self.program, \
                    enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):
                view_matrix = (
                    Matrix4
                    # .new_scale(2/w, 2/h, 1/max(w, h))
                    .new_translate(0, 0, -5)
                    .rotatex(math.pi)
                    .rotatez(azimuth)  # Rotate over time
                )
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      gl_matrix(frust * view_matrix * model_matrix))

                gl.glViewport(0, 0, *size)
                gl.glPointSize(1.0)

                mesh.draw(mode=gl.GL_POINTS)

            final_buffer = self._get_final_buffer(size)
            
            with self._vao, final_buffer, self._copy_program, disabled(gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
                with offscreen_buffer["color"], offscreen_buffer["normal"], offscreen_buffer["position"], shadow_buffer["depth"]:
                    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
                
            # TODO must be careful here so that the texture is always valid
            # (since imgui may read it at any time) Find a way to ensure this.
            texture = self._get_texture(size)
            gl.glCopyImageSubData(final_buffer["color"].name, gl.GL_TEXTURE_2D, 0, 0, 0, 0,
                                  texture.name, gl.GL_TEXTURE_2D, 0, 0, 0, 0,
                                  w, h, 1)
            self.texture = texture, size
Beispiel #21
0
    def on_draw(self):

        # Prevent trying to draw before things have been set up
        if not hasattr(self, "offscreen_buffer"):
            return

        # Model matrix we'll use to position the main model
        suzanne_model_matrix = (Matrix4.new_identity().rotatex(
            -math.pi / 2).rotatez(time()))  # Rotate over time
        plane_model_matrix = Matrix4.new_rotatey(math.pi).translate(0, 0, 2)

        # Render to an offscreen buffer
        with self.offscreen_buffer, self.view_program, \
                enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

            gl.glDepthMask(gl.GL_TRUE)

            w, h = self.size
            aspect = h / w

            # Calculate a view frustum; this is basically our camera.
            near = 5
            far = 15
            width = 2
            height = 2 * aspect
            frustum = (Matrix4.new(near / width, 0, 0, 0, 0, near / height, 0,
                                   0, 0, 0, -(far + near) / (far - near), -1,
                                   0, 0, -2 * far * near / (far - near), 0))

            # The view matrix positions the camera in the scene
            view_matrix = (Matrix4.new_identity().translate(0, 0, -8))

            # Send the matrices to GL
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                  gl_matrix(frustum * view_matrix))
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(suzanne_model_matrix))

            gl.glUniform4f(2, 0.3, 0.3, 1,
                           1)  # Set the "color" uniform to blue
            self.suzanne.draw()

            # We'll also draw a simple plane behind the main model
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(plane_model_matrix))
            gl.glUniform4f(2, 0.3, 1, 0.3,
                           1)  # Set the "color" uniform to green
            self.plane.draw(mode=gl.GL_TRIANGLE_STRIP)

        # Render shadow buffer
        # Basically the same scene as above, but to a different buffer and from a different view
        with self.shadow_buffer, self.view_program, enabled(
                gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):
            gl.glDepthMask(gl.GL_TRUE)

            frustum = Matrix4.new_perspective(1, 1, 1, 12)
            view_matrix = (Matrix4.new_identity().translate(
                0, 0, -4).rotatey(0.5).rotatex(0.3))
            light_pos = (view_matrix.inverse() * Point3(0, 0, 0))
            light_view_matrix = frustum * view_matrix
            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                  gl_matrix(light_view_matrix))
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(suzanne_model_matrix))
            gl.glUniform4f(2, 0.9, 0.3, 0.4, 1)
            self.suzanne.draw()

            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(plane_model_matrix))
            self.plane.draw(mode=gl.GL_TRIANGLE_STRIP)

        # Now draw the offscreen buffer to another buffer, combining it with the
        # lighting information to get a nice image.
        # Note: This step is pretty pointless here, as we might just draw directly to screen.
        # Just demonstrates how to do it.
        with self.vao, self.offscreen_buffer2, self.lighting_program, disabled(
                gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
            gl.glUniform3f(0, *light_pos)
            gl.glUniformMatrix4fv(1, 1, gl.GL_FALSE,
                                  gl_matrix(light_view_matrix))
            # Bind some of the offscreen buffer's textures so the shader can read them.
            with self.offscreen_buffer["color"], self.offscreen_buffer["normal"], \
                    self.offscreen_buffer["position"], self.shadow_buffer["depth"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

        # Now render the finished image to the screen
        with self.vao, self.copy_program, disabled(gl.GL_CULL_FACE,
                                                   gl.GL_DEPTH_TEST):
            with self.offscreen_buffer2["color"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
Beispiel #22
0
    def on_draw(self):

        gl.glClearBufferfv(gl.GL_COLOR, 0, BG_COLOR)

        if self.drawing:

            window_size = self.get_pixel_aligned_size()
            w, h = self.drawing.size

            vm = (gl.GLfloat * 16)(*make_view_matrix(
                window_size, self.drawing.size, self.zoom, self.offset))
            offscreen_buffer = render_drawing(self.drawing,
                                              self.highlighted_layer)

            ww, wh = window_size
            gl.glViewport(0, 0, int(ww), int(wh))

            # Draw a background rectangle
            with self.vao, self.copy_program:
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      (gl.GLfloat * 16)(*vm))
                if self.drawing and self.drawing.grid:
                    with self.get_background_texture(
                            self.drawing.palette.colors[0], 0.9):
                        gw, gh = self.drawing.grid_size
                        gl.glUniform2f(1, w / (gw * 2), h / (gh * 2))
                        gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
                        gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
                else:
                    #gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
                    # r, g, b, _ = self.drawing.palette.get_color_as_float(self.drawing.palette.colors[0])
                    # gl.glClearColor(r, g, b, 1)
                    # TODO should fill with color 0 here!
                    # gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
                    with self.get_background_texture(
                            self.drawing.palette.colors[0], 1):
                        gw, gh = self.drawing.grid_size
                        gl.glUniform2f(1, w / (gw * 2), h / (gh * 2))
                        gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
                        gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

                with offscreen_buffer["color"]:
                    gl.glUniform2f(1, 1, 1)
                    gl.glEnable(gl.GL_BLEND)
                    gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA)
                    gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, vm)
                    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

            with self.line_program:
                with self.border_vao:
                    self.update_border(self.drawing.current.rect)
                    gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, vm)
                    # r, g, b, _ = self.drawing.palette.get_color_as_float(self.drawing.palette.colors[0])
                    # gl.glUniform3f(1, r, g, b)
                    # gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, 4)
                    gl.glUniform3f(1, 0., 0., 0.)
                    gl.glLineWidth(1)
                    gl.glDrawArrays(gl.GL_LINE_LOOP, 0, 4)

                # Selection rectangle
                if self.stroke:
                    tool = self.stroke.tool
                    selection = ((tool and tool.show_rect and tool.rect)
                                 or self.selection)
                    if selection:
                        self.set_selection(selection)
                        with self.selection_vao:
                            gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, vm)
                            gl.glUniform3f(1, 1., 1., 0.)
                            gl.glLineWidth(1)
                            gl.glDrawArrays(gl.GL_LINE_LOOP, 0, 4)

        if not self.tablet.active:
            self._draw_mouse_cursor()

        ui.draw_ui(self)

        gl.glFinish(
        )  # No double buffering, to minimize latency (does this work?)
Beispiel #23
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))
 def uniform_matrix(self, location, matrix):
     gl.glUniformMatrix4fv(location, 1, gl.GL_FALSE,
                           (gl.GLfloat * 16)(*sum(matrix.data, [])))
Beispiel #25
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, (c_float * 16)(*mat))
Beispiel #26
0
        def __init__(self):
            #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.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]
            self.dimz = args["A"].shape[2]

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

            #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))

            T = args["transform"].astype(np.float32)

            self.Tp = T.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

            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 = gl.glGetUniformLocation(self.programA, b"A")
            self.transform_pos = gl.glGetUniformLocation(
                self.programA, b"transform")
            self.step_pos_A = gl.glGetUniformLocation(self.programA, b"step")
            self.slice_pos_A = gl.glGetUniformLocation(self.programA, b"slice")
            self.checkUniformLocation(self.tex_pos_A)
            self.checkUniformLocation(self.transform_pos)
            self.checkUniformLocation(self.step_pos_A)
            self.checkUniformLocation(self.slice_pos_A)

            gl.glUniformMatrix4fv(self.transform_pos, 1, True, self.Tp)
            #gl.glUniformMatrix4fv(self.transform_pos, 1, False, self.Tp)
            #may need changed for nonsquare textures
            gl.glUniform1f(self.step_pos_A, 1 / self.dimx)

            gl.glViewport(0, 0, self.dimx, self.dimy)
Beispiel #27
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))
Beispiel #28
0
    def render(self, draw_data):
        # perf: local for faster access
        io = self.io

        display_width, display_height = io.display_size
        fb_width = int(display_width * io.display_fb_scale[0])
        fb_height = int(display_height * io.display_fb_scale[1])

        if fb_width == 0 or fb_height == 0:
            return

        draw_data.scale_clip_rects(*io.display_fb_scale)

        # backup GL state
        # todo: provide cleaner version of this backup-restore code
        last_program = gl.GLint()
        gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(last_program))
        last_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture))
        last_active_texture = gl.GLint()
        gl.glGetIntegerv(gl.GL_ACTIVE_TEXTURE, byref(last_active_texture))
        last_array_buffer = gl.GLint()
        gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer))
        last_element_array_buffer = gl.GLint()
        gl.glGetIntegerv(gl.GL_ELEMENT_ARRAY_BUFFER_BINDING, byref(last_element_array_buffer))
        last_vertex_array = gl.GLint()
        gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array))
        last_blend_src = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_SRC, byref(last_blend_src))
        last_blend_dst = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_DST, byref(last_blend_dst))
        last_blend_equation_rgb = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_EQUATION_RGB, byref(last_blend_equation_rgb))
        last_blend_equation_alpha = gl.GLint()
        gl.glGetIntegerv(gl.GL_BLEND_EQUATION_ALPHA, byref(last_blend_equation_alpha))
        last_viewport = (gl.GLint*4)()
        gl.glGetIntegerv(gl.GL_VIEWPORT, last_viewport)
        last_scissor_box = (gl.GLint*4)()
        gl.glGetIntegerv(gl.GL_SCISSOR_BOX, last_scissor_box)
        last_enable_blend = gl.GLint()
        gl.glIsEnabled(gl.GL_BLEND, byref(last_enable_blend))
        last_enable_cull_face = gl.GLint()
        gl.glIsEnabled(gl.GL_CULL_FACE, byref(last_enable_cull_face))
        last_enable_depth_test = gl.GLint()
        gl.glIsEnabled(gl.GL_DEPTH_TEST, byref(last_enable_depth_test))
        last_enable_scissor_test = gl.GLint()
        gl.glIsEnabled(gl.GL_SCISSOR_TEST, byref(last_enable_scissor_test))

        gl.glEnable(gl.GL_BLEND)
        gl.glBlendEquation(gl.GL_FUNC_ADD)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        gl.glDisable(gl.GL_CULL_FACE)
        gl.glDisable(gl.GL_DEPTH_TEST)
        gl.glEnable(gl.GL_SCISSOR_TEST)
        gl.glActiveTexture(gl.GL_TEXTURE0)

        gl.glViewport(0, 0, int(fb_width), int(fb_height))

        ortho_projection = [
            2.0/display_width, 0.0,                   0.0, 0.0,
            0.0,               2.0/-display_height,   0.0, 0.0,
            0.0,               0.0,                  -1.0, 0.0,
            -1.0,               1.0,                   0.0, 1.0
        ]

        gl.glUseProgram(self._shader_handle)
        gl.glUniform1i(self._attrib_location_tex, 0)
        gl.glUniformMatrix4fv(self._attrib_proj_mtx, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*ortho_projection))
        gl.glBindVertexArray(self._vao_handle)

        for commands in draw_data.commands_lists:
            idx_buffer_offset = 0

            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle)
            # todo: check this (sizes)
            gl.glBufferData(gl.GL_ARRAY_BUFFER, commands.vtx_buffer_size * imgui.VERTEX_SIZE, c_void_p(commands.vtx_buffer_data), gl.GL_STREAM_DRAW)

            gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._elements_handle)
            # todo: check this (sizes)
            gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, commands.idx_buffer_size * imgui.INDEX_SIZE, c_void_p(commands.idx_buffer_data), gl.GL_STREAM_DRAW)

            # todo: allow to iterate over _CmdList
            for command in commands.commands:
                gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id)

                # todo: use named tuple
                x, y, z, w = command.clip_rect
                gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y))

                if imgui.INDEX_SIZE == 2:
                    gltype = gl.GL_UNSIGNED_SHORT
                else:
                    gltype = gl.GL_UNSIGNED_INT

                gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, c_void_p(idx_buffer_offset))

                idx_buffer_offset += command.elem_count * imgui.INDEX_SIZE

        # restore modified GL state
        gl.glUseProgram(cast((c_int*1)(last_program), POINTER(c_uint)).contents)
        gl.glActiveTexture(cast((c_int*1)(last_active_texture), POINTER(c_uint)).contents)
        gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents)
        gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents)
        gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, cast((c_int*1)(last_element_array_buffer), POINTER(c_uint)).contents)
        gl.glBlendEquationSeparate(cast((c_int*1)(last_blend_equation_rgb), POINTER(c_uint)).contents,
                                   cast((c_int*1)(last_blend_equation_alpha), POINTER(c_uint)).contents)
        gl.glBlendFunc(cast((c_int*1)(last_blend_src), POINTER(c_uint)).contents,
                       cast((c_int*1)(last_blend_dst), POINTER(c_uint)).contents)

        if last_enable_blend:
            gl.glEnable(gl.GL_BLEND)
        else:
            gl.glDisable(gl.GL_BLEND)

        if last_enable_cull_face:
            gl.glEnable(gl.GL_CULL_FACE)
        else:
            gl.glDisable(gl.GL_CULL_FACE)

        if last_enable_depth_test:
            gl.glEnable(gl.GL_DEPTH_TEST)
        else:
            gl.glDisable(gl.GL_DEPTH_TEST)

        if last_enable_scissor_test:
            gl.glEnable(gl.GL_SCISSOR_TEST)
        else:
            gl.glDisable(gl.GL_SCISSOR_TEST)

        gl.glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
        gl.glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
Beispiel #29
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))
Beispiel #30
0
    def __call__(self,
                 voxpaint,
                 drawing,
                 altitude: float = 120,
                 azimuth: float = 45,
                 spin: bool = False):

        size = drawing.size
        depth = drawing.shape[2]
        colors = drawing.palette.colors

        x = math.sin(math.pi / 3)

        altitude = math.radians(altitude)
        azimuth = math.radians(azimuth)

        mesh = self._get_mesh(drawing, drawing.version,
                              drawing.hidden_layers_by_axis)
        if not mesh:
            # TODO hacky
            self.texture and self.texture[0].clear()
            return

        w, h = size
        vw = int(w * math.sqrt(2))
        vh = int(h + math.sqrt(2) * h // 2)
        view_size = (vw, vh)
        model_matrix = (Matrix4.new_scale(1, 1, 1 / x).translate(
            -w // 2, -h // 2, depth // 2 - 1 / 2))

        far = w * 2
        near = -w * 2
        frust = Matrix4()
        frust[:] = (2 / vw, 0, 0, 0, 0, 2 / vh, 0, 0, 0, 0, -2 / (far - near),
                    0, 0, 0, -(far + near) / (far - near), 1)

        offscreen_buffer = self._get_buffer(view_size)
        with offscreen_buffer, self.program, \
                enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

            azimuth = time() if spin else azimuth
            view_matrix = (
                Matrix4.new_translate(0, 0, -1).rotatex(altitude).rotatez(
                    azimuth)  # Rotate over time
            )
            colors = self._get_colors(colors)
            gl.glUniform4fv(3, 256, colors)

            gl.glUniformMatrix4fv(
                0, 1, gl.GL_FALSE,
                gl_matrix(frust * view_matrix * model_matrix))
            gl.glViewport(0, 0, vw, vh)
            gl.glPointSize(1)

            mesh.draw(mode=gl.GL_POINTS)

        final_buffer = self._get_final_buffer(view_size)

        with self._vao, final_buffer, self._copy_program, disabled(
                gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
            with offscreen_buffer["color"], offscreen_buffer[
                    "normal"], offscreen_buffer["position"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

        # TODO must be careful here so that the texture is always valid
        # (since imgui may read it at any time) Find a way to ensure this.
        texture = self._get_texture(view_size)
        gl.glCopyImageSubData(final_buffer["color"].name, gl.GL_TEXTURE_2D, 0,
                              0, 0, 0, texture.name, gl.GL_TEXTURE_2D, 0, 0, 0,
                              0, vw, vh, 1)
        self.texture = texture, view_size
Beispiel #31
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))
     
Beispiel #32
0
 def uniform_matrixf(self, name, mat, loc=None):
     """Send 4x4 NumPy matrix data as a uniform to the shader, named 'name'. Shader must be already bound."""
     # obtain the uniform location
     if not loc:
         loc = self.get_uniform_location(name)
     gl.glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*mat))  # uplaod the 4x4 floating point matrix
Beispiel #33
0
def _umat4(uniform, matrix):
    data_array = (gl.GLfloat * 16)(*matrix[:])
    gl.glUniformMatrix4fv(uniform, 1, gl.GL_FALSE, data_array)
Beispiel #34
0
    GLint: glGetUniformiv
}        
        
UNIFORMS_DATA = { 
# TypeIndentifier: (c_type, buffer_length, setter, [matrix_size])
  GL_FLOAT: (GLfloat, 1, glUniform1fv),
  GL_FLOAT_VEC2: (GLfloat, 2, glUniform2fv),
  GL_FLOAT_VEC3: (GLfloat, 3, glUniform3fv),
  GL_FLOAT_VEC4: (GLfloat, 4, glUniform4fv),
  GL_INT: (GLint, 1, glUniform1iv),
  GL_INT_VEC2: (GLint, 2, glUniform2iv),
  GL_INT_VEC3: (GLint, 3, glUniform3iv),
  GL_INT_VEC4: (GLint, 4, glUniform4iv),
  GL_FLOAT_MAT2: (GLfloat, 4, lambda x,y,z: glUniformMatrix2fv(x,y,TRANSPOSE_MATRIX,z),      (2,2)),
  GL_FLOAT_MAT3: (GLfloat, 9, lambda x,y,z: glUniformMatrix3fv(x,y,TRANSPOSE_MATRIX,z),      (3,3)),
  GL_FLOAT_MAT4: (GLfloat, 16, lambda x,y,z: glUniformMatrix4fv(x,y,TRANSPOSE_MATRIX,z),     (4,4)),
  GL_FLOAT_MAT2x3: (GLfloat, 6, lambda x,y,z: glUniformMatrix2x3fv(x,y,TRANSPOSE_MATRIX,z),  (2,3)),
  GL_FLOAT_MAT2x4: (GLfloat, 8, lambda x,y,z: glUniformMatrix2x4fv(x,y,TRANSPOSE_MATRIX,z),  (2,4)),
  GL_FLOAT_MAT3x2: (GLfloat, 6, lambda x,y,z: glUniformMatrix3x2fv(x,y,TRANSPOSE_MATRIX,z),  (3,2)),
  GL_FLOAT_MAT3x4: (GLfloat, 12, lambda x,y,z: glUniformMatrix3x4fv(x,y,TRANSPOSE_MATRIX,z), (3,4)),
  GL_FLOAT_MAT4x2: (GLfloat, 8, lambda x,y,z: glUniformMatrix4x2fv(x,y,TRANSPOSE_MATRIX,z),  (4,2)),
  GL_FLOAT_MAT4x3: (GLfloat, 12, lambda x,y,z: glUniformMatrix4x3fv(x,y,TRANSPOSE_MATRIX,z), (4,3)),
} 

UNPACK_ARRAY = [GL_FLOAT, GL_INT]

to_seq = lambda x: x if isinstance(x, Sequence) else [x] 

def as_matrix(values, size):
    "Transform a flat list into a matrix"
    row, col = size
Beispiel #35
0
 GL_FLOAT_VEC2: (GLfloat, 2, glUniform2fv),
 GL_FLOAT_VEC3: (GLfloat, 3, glUniform3fv),
 GL_FLOAT_VEC4: (GLfloat, 4, glUniform4fv),
 GL_INT: (GLint, 1, glUniform1iv),
 GL_INT_VEC2: (GLint, 2, glUniform2iv),
 GL_INT_VEC3: (GLint, 3, glUniform3iv),
 GL_INT_VEC4: (GLint, 4, glUniform4iv),
 GL_FLOAT_MAT2:
 (GLfloat, 4, lambda x, y, z: glUniformMatrix2fv(x, y, TRANSPOSE_MATRIX, z),
  (2, 2)),
 GL_FLOAT_MAT3:
 (GLfloat, 9, lambda x, y, z: glUniformMatrix3fv(x, y, TRANSPOSE_MATRIX, z),
  (3, 3)),
 GL_FLOAT_MAT4:
 (GLfloat, 16,
  lambda x, y, z: glUniformMatrix4fv(x, y, TRANSPOSE_MATRIX, z), (4, 4)),
 GL_FLOAT_MAT2x3:
 (GLfloat, 6,
  lambda x, y, z: glUniformMatrix2x3fv(x, y, TRANSPOSE_MATRIX, z), (2, 3)),
 GL_FLOAT_MAT2x4:
 (GLfloat, 8,
  lambda x, y, z: glUniformMatrix2x4fv(x, y, TRANSPOSE_MATRIX, z), (2, 4)),
 GL_FLOAT_MAT3x2:
 (GLfloat, 6,
  lambda x, y, z: glUniformMatrix3x2fv(x, y, TRANSPOSE_MATRIX, z), (3, 2)),
 GL_FLOAT_MAT3x4:
 (GLfloat, 12,
  lambda x, y, z: glUniformMatrix3x4fv(x, y, TRANSPOSE_MATRIX, z), (3, 4)),
 GL_FLOAT_MAT4x2:
 (GLfloat, 8,
  lambda x, y, z: glUniformMatrix4x2fv(x, y, TRANSPOSE_MATRIX, z), (4, 2)),
Beispiel #36
0
 def uniform_matrix(self, location, matrix):
     gl.glUniformMatrix4fv(location, 1, gl.GL_FALSE, glm.value_ptr(matrix))