Beispiel #1
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)
Beispiel #2
0
def render(shape: VertexBuffer):
    """
    Render an shape previously created with a ``create`` function.
    """
    # Set color
    if shape.color is None:
        raise ValueError("Error: Color parameter not set.")

    gl.glLoadIdentity()
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, shape.vbo_vertex_id)
    gl.glVertexPointer(2, gl.GL_FLOAT, 0, 0)

    if shape.line_width:
        gl.glLineWidth(shape.line_width)

    if len(shape.color) == 4:
        gl.glColor4ub(shape.color[0], shape.color[1], shape.color[2],
                      shape.color[3])
        gl.glEnable(gl.GL_BLEND)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
    elif len(shape.color) == 3:
        gl.glDisable(gl.GL_BLEND)
        gl.glColor4ub(shape.color[0], shape.color[1], shape.color[2], 255)

    gl.glDrawArrays(shape.draw_mode, 0, shape.size)
Beispiel #3
0
    def draw(self, uniforms, text, quad, textures=(), *args, **kwargs):
        glUseProgram(self)
        glDisable(GL_DEPTH_TEST)


        quad.enable()

        glUniform3f(self.uniforms[b'color'], 0.3, 0.3, 0.5)

        glUniformMatrix3fv(
            self.uniforms[b'transformation'], 1, GL_TRUE,
            text.get_transformation_matrix_2D().ctypes.data_as(POINTER(GLfloat))
        )

        textures.enable(slot=0)
        glUniform1i(self.uniforms[b'font_atlas'], 0)

        quad.draw()

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

        glBindTexture(GL_TEXTURE_2D, 0)

        glDisableVertexAttribArray(0)

        glEnable(GL_DEPTH_TEST)
Beispiel #4
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 #5
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)
def render_to_texture():
    # select the target to draw into
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer)
    draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
    gl.glDrawBuffers(1, draw_buffers)
    gl.glViewport(0, 0, FB_WIDTH, FB_HEIGHT)

    # clear the destination
    gl.glClearColor(0.5, 0.6, 0.7, 1.0)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    # prepare the rendering
    gl.glUseProgram(render_program)

    # send the vertex data
    data = (COLOR_VERTEX * 3)(((-0.6, -0.5), (1.0, 0.0, 0.0, 1.0)),
                      ((0.6, -0.5), (0.0, 1.0, 0.0, 1.0)),
                      ((0.0, 0.5), (0.0, 0.0, 1.0, 1.0)))

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data, gl.GL_DYNAMIC_DRAW)

    # draw using the vertex array for vertex information
    gl.glBindVertexArray(render_vao)
    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
    gl.glBindVertexArray(0)
def copy_texture_to_screen():
    # select the target to draw into
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
    gl.glViewport(0, 0, window.width, window.height)

    # clear the destination
    gl.glClearColor(0.4, 0.4, 0.4, 1.0)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    # select the program for drawing
    gl.glUseProgram(copy_program)

    # send the vertex data
    data = (TEXTURE_VERTEX * 8)(((-0.9, -0.9), (0.0, 0.0)),
                                ((0.5, -0.9), (1.0, 0.0)),
                                ((0.5, 0.5), (1.0, 1.0)),
                                ((-0.9, 0.5), (0.0, 1.0)),

                                ((0.6, 0.6), (0.0, 1.0)),
                                ((1.0, 0.6), (1.0, 1.0)),
                                ((1.0, 1.0), (1.0, 0.0)),
                                ((0.6, 1.0), (0.0, 0.0)),
                                )

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data, gl.GL_DYNAMIC_DRAW)


    # draw
    gl.glBindVertexArray(copy_vao)
    gl.glDrawArrays(gl.GL_QUADS, 0, 8)
    gl.glBindVertexArray(0)
Beispiel #8
0
def _draw_rects(shape_list, vertex_vbo_id, texture_coord_vbo_id):
    """
    Draw a set of rectangles using vertex buffers. This is more efficient
    than drawing them individually.
    """
    GL.glEnable(GL.GL_BLEND)
    GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
    GL.glEnable(GL.GL_TEXTURE_2D)
    GL.glHint(GL.GL_POLYGON_SMOOTH_HINT, GL.GL_NICEST)
    GL.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST)

    # GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
    # GL.glMatrixMode(GL.GL_MODELVIEW)
    # GL.glDisable(GL.GL_BLEND)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertex_vbo_id)
    GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
    GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
    GL.glVertexPointer(2, GL.GL_FLOAT, 0, 0)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, texture_coord_vbo_id)

    offset = 0
    for shape in shape_list:
        if shape.can_cache:
            texture_coord_vbo_id = None

            GL.glColor4f(1, 1, 1, shape.alpha)

            _render_rect_filled(shape, offset,
                                shape.texture.texture_id, texture_coord_vbo_id)

            offset += 4
        else:
            shape.draw()
def setup_copy_vertexbuffer():
    '''
    Create the vertexbuffer object for the copying program
    '''
    # gl.glGenVertexArrays(1, ctypes.byref(copy_vao))
    gl.glGenBuffers(1, ctypes.byref(copy_vertexbuffer))

    loc_position = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'position'))
    loc_texcoord = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'texcoord'))

    if loc_position < 0:
        print('Warning: position is not used in the shader')
    if loc_texcoord < 0:
        print('Warning: texcoord is not used in the shader')

    gl.glBindVertexArray(copy_vao)

    gl.glEnableVertexAttribArray(loc_position)
    gl.glEnableVertexAttribArray(loc_texcoord)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer)

    gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.position.offset))
    gl.glVertexAttribPointer(loc_texcoord, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.texcoord.offset))

    gl.glBindVertexArray(0)
Beispiel #10
0
 def create_with_size(cls, size: int, usage: str = 'static'):
     """Create an empty Buffer storage of the given size."""
     empty_buffer = Buffer(b"", usage=usage)
     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, empty_buffer.buffer_id)
     gl.glBufferData(gl.GL_ARRAY_BUFFER, size, None, Buffer.usages[usage])
     empty_buffer.size = size
     return empty_buffer
Beispiel #11
0
    def draw(self, shader):
        attribute_table = shader.attribute_table

        self.indexed_vbo.bind()

        # Bind all attributes.
        location_list = []  # Used to disable all VertexAttribArrays.
        for name, vbo in self.vbo_array.items():
            vbo.bind()
            attribute_location = attribute_table[name]
            location_list.append(attribute_location)
            glEnableVertexAttribArray(attribute_location)
            # specify that the data for the attribute will be pulled from the buffer that is currently bound to
            # GL_ARRAY_BUFFER. (http://stackoverflow.com/questions/30016833/multiple-in-attributes-in-shader-opengl)
            glVertexAttribPointer(attribute_location, vbo.dimension,
                                  vbo.data_type, GL_FALSE, 0, 0)

        # Draw.
        # glDrawArrays(GL_TRIANGLES, 0, vbo.count)
        glDrawElements(GL_TRIANGLES, self.indexed_vbo.count,
                       self.indexed_vbo.data_type, 0)

        # Disable and unbind everything.
        for location in location_list:
            glDisableVertexAttribArray(location)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
Beispiel #12
0
    def __init__(self):
        self.fbo = gl.GLuint(0)
        self.rendered_texture = gl.GLuint(0)
        self.depthrenderbuffer = gl.GLuint(0)
        self.pickingbuffer = gl.GLuint(0)
        self.vertex_buffer = gl.GLuint(0)

        self.program = GlProgram(shaders.vertex_copy, shaders.fragment_copy)
        gl.glGenBuffers(1, pointer(self.vertex_buffer))
        data = (gl.GLfloat * 16)(-1, -1, 0, 0,
                                 - 1, 1, 0, 1,
                                  1, 1, 1, 1,
                                  1, -1, 1, 0)

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW)

        gl.glGenFramebuffers(1, pointer(self.fbo))
        if not self.fbo:
            logging.error('failed fbo')
        gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo)

        gl.glGenTextures(1, pointer(self.rendered_texture))
        if not self.rendered_texture:
            logging.error('failed rendered_texture')

        gl.glGenRenderbuffers(1, pointer(self.depthrenderbuffer))
        gl.glGenRenderbuffers(1, pointer(self.pickingbuffer))

        self.resize(1, 1)
Beispiel #13
0
    def _enable_attrib(self, buf_desc: BufferDescription):
        buff = buf_desc.buffer
        stride = sum(attribsize for _, attribsize, _ in buf_desc.formats)

        if buf_desc.instanced:
            if self.num_vertices == -1:
                raise ShaderException(
                    "The first vertex attribute cannot be a per instance attribute."
                )
        else:
            self.num_vertices = max(self.num_vertices, buff.size // stride)
            # print(f"Number of vertices: {self.num_vertices}")

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buff.buffer_id)
        offset = 0
        for (size, attribsize,
             gl_type_enum), attrib in zip(buf_desc.formats,
                                          buf_desc.attributes):
            loc = gl.glGetAttribLocation(self.program, attrib.encode('utf-8'))
            if loc == -1:
                raise ShaderException(
                    f"Attribute {attrib} not found in shader program")
            normalized = gl.GL_TRUE if attrib in buf_desc.normalized else gl.GL_FALSE
            gl.glVertexAttribPointer(loc, size, gl_type_enum, normalized,
                                     stride, c_void_p(offset))
            # print(f"{attrib} of size {size} with stride {stride} and offset {offset}")
            if buf_desc.instanced:
                gl.glVertexAttribDivisor(loc, 1)
            offset += attribsize
            gl.glEnableVertexAttribArray(loc)
Beispiel #14
0
    def set_vertex_attrib(self, name, data):
        """This is an ugly way to set vertex attribute data in a shader, it lacks
        the flexibility of setting several attributes in one vertex buffer.

        name: the attribute name in the shader.
        data: a list of vertex attributes (positions, colors, texcoords, normals,...)
        example: name = 'positions', data = [(1, 1, 0), (2, 2, 1), ...]
        the items in data must all be 1D lists(or tuples) of the same length.
        """
        data_flatten = [x for vertex in data for x in vertex]
        size = len(data[0])
        data_ctype = (gl.GLfloat * len(data_flatten))(*data_flatten)

        vbo_id = gl.GLuint(0)
        gl.glGenBuffers(1, ct.byref(vbo_id))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype,
                        gl.GL_STATIC_DRAW)

        location = gl.glGetAttribLocation(self.program, name.encode('ascii'))
        gl.glEnableVertexAttribArray(location)
        gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE, 0,
                                 0)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
        return vbo_id
Beispiel #15
0
    def on_draw(self):
        """
        Render the screen.
        """
        start = time.time()

        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glMatrixMode(GL.GL_MODELVIEW)
        GL.glDisable(GL.GL_BLEND)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vertex_vbo_id)
        GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
        GL.glVertexPointer(2, GL.GL_FLOAT, 0, 0)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.color_vbo_id)
        GL.glEnableClientState(GL.GL_COLOR_ARRAY)
        GL.glColorPointer(3, GL.GL_FLOAT, 0, 0)

        offset = 0
        for shape in self.shape_list:
            render_rect_filled(shape, offset)
            offset += 4

        elapsed = time.time() - start
        print(elapsed)
    def read(self, size=-1, offset=0) -> bytes:
        """Read data from the buffer.

        :param int size: The bytes to read. -1 means the entire buffer (default)
        :param int offset: Byte read offset
        :rtype: bytes
        """
        if size == -1:
            size = self._size

        # Catch this before confusing INVALID_OPERATION is raised
        if size < 1:
            raise ValueError("Attempting to read 0 or less bytes from buffer")

        # Manually detect this so it doesn't raise a confusing INVALID_VALUE error
        if size + offset > self._size:
            raise ValueError(
                (
                    "Attempting to read outside the buffer. "
                    f"Buffer size: {self._size} "
                    f"Reading from {offset} to {size + offset}"
                )
            )

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
        ptr = gl.glMapBufferRange(gl.GL_ARRAY_BUFFER, offset, size, gl.GL_MAP_READ_BIT)
        data = string_at(ptr, size=size)
        gl.glUnmapBuffer(gl.GL_ARRAY_BUFFER)
        return data
Beispiel #17
0
    def set_vertex_attrib(self, name, data):
        '''
        this is an ugly way to set vertex attribute data in a shader.
        lacks the flexibility of setting several attributes in one vertex buffer.

        name: the attribute name in the shader.
        data: a list of vertex attributes (positions, colors, texcoords, normals,...)

        example:
        name = 'positions'
        data = [(1, 1, 0), (2, 2, 1), ...]

        the items in data must all be 1D lists(or tuples) of the same length.
        '''
        data_flatten = [x for vertex in data for x in vertex]
        size = len(data[0])
        data_ctype = (gl.GLfloat * len(data_flatten))(*data_flatten)

        vbo_id = gl.GLuint(0)
        gl.glGenBuffers(1, ct.byref(vbo_id))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype, gl.GL_STATIC_DRAW)

        location = gl.glGetAttribLocation(self.program, name.encode('ascii'))
        gl.glEnableVertexAttribArray(location)
        gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
        return vbo_id
def setup_render_vertexbuffer():
    '''
    Create the vertexbuffer object for the rendering program
    '''
    gl.glGenVertexArrays(1, ctypes.byref(render_vao))
    gl.glGenBuffers(1, ctypes.byref(render_vertexbuffer))

    loc_position = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'position'))
    loc_color = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'color'))

    if loc_position < 0:
        print('Warning: position is not used in the shader')
    if loc_color < 0:
        print('Warning: color is not used in the shader')


    gl.glBindVertexArray(render_vao)

    gl.glEnableVertexAttribArray(loc_position)
    gl.glEnableVertexAttribArray(loc_color)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer)

    gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.position.offset))
    gl.glVertexAttribPointer(loc_color, 4, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.color.offset))

    gl.glBindVertexArray(0)
Beispiel #19
0
    def send_data(self, data):
        data = (self.VERTEX * len(data))(*data)

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer_name)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data,
                        gl.GL_DYNAMIC_DRAW)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
Beispiel #20
0
    def __init__(self, data, dimension=3):
        """
        Vertex Buffer Object for storing data in OpenGl.

        Args:
            data: An array of values.
            dimension: Whether the array is 1D, 2D, 3D or 4D.
        """
        data_type = c_float
        elements = len(data)

        buffer_type = data_type * elements
        buffer = buffer_type()
        buffer[:] = data  # About 2.5 times faster than passing arguments during initialization.

        handle = c_uint()
        glGenBuffers(1, handle)
        glBindBuffer(GL_ARRAY_BUFFER, handle)
        glBufferData(GL_ARRAY_BUFFER, elements * sizeof(data_type), buffer,
                     GL_STATIC_DRAW)
        glBindBuffer(GL_ARRAY_BUFFER, 0)

        super(VBO, self).__init__(handle.value)
        self.data_type = GL_FLOAT
        self.count = elements // dimension
        self.dimension = dimension
Beispiel #21
0
    def __init__(self, **args):
        super(Window, self).__init__(**args)

        self.vao = gl.GLuint(0)
        gl.glGenVertexArrays(1, ctypes.byref(self.vao))
        gl.glBindVertexArray(self.vao)

        self.vbo = gl.GLuint(0)
        gl.glGenBuffers(1, ctypes.byref(self.vbo))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo)

        gl.glBufferData(gl.GL_ARRAY_BUFFER,
                        ctypes.sizeof(gl.GLfloat * len(vertex_positions)),
                        (gl.GLfloat *
                         len(vertex_positions))(*vertex_positions),
                        gl.GL_STATIC_DRAW)

        gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
        gl.glEnableVertexAttribArray(0)

        self.ibo = gl.GLuint(0)
        gl.glGenBuffers(1, self.ibo)
        gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo)

        gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER,
                        ctypes.sizeof(gl.GLuint * len(indices)),
                        (gl.GLuint * len(indices))(*indices),
                        gl.GL_STATIC_DRAW)
Beispiel #22
0
    def data(self, buffer_type, data, offset):
        if buffer_type != "texture":
            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers[buffer_type])

            if buffer_type == "color":
                offset *= 16
            else:
                offset *= 12

            gl_data = to_gl_float(data)
            length = len(data) * 4
            gl.glBufferSubData(gl.GL_ARRAY_BUFFER, offset, length, gl_data)

            if buffer_type == "vertex":
                self.vertex_count += int(len(data) / 3)

        else:
            self.buffers["texture"] = gl.GLuint(0)
            gl.glGenTextures(1, self.buffers["texture"])
            gl.glBindTexture(data.target, data.id)

            gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
            gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)

            gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, texture.width, texture.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE,
                            texture_data)
    def copy_from_buffer(self, source: "Buffer", size=-1, offset=0, source_offset=0):
        """Copy data into this buffer from another buffer

        :param Buffer source: The buffer to copy from
        :param int size: The amount of bytes to copy
        :param int offset: The byte offset to write the data in this buffer
        :param int source_offset: The byte offset to read from the source buffer
        """
        # Read the entire source buffer into this buffer
        if size == -1:
            size = source.size

        # TODO: Check buffer bounds
        if size + source_offset > source.size:
            raise ValueError("Attempting to read outside the source buffer")

        if size + offset > self._size:
            raise ValueError("Attempting to write outside the buffer")

        gl.glBindBuffer(gl.GL_COPY_READ_BUFFER, source.glo)
        gl.glBindBuffer(gl.GL_COPY_WRITE_BUFFER, self._glo)
        gl.glCopyBufferSubData(
            gl.GL_COPY_READ_BUFFER,
            gl.GL_COPY_WRITE_BUFFER,
            gl.GLintptr(source_offset),  # readOffset
            gl.GLintptr(offset),  # writeOffset
            size,  # size (number of bytes to copy)
        )
Beispiel #24
0
def setup_render_vertexbuffer():
    '''
	Create the vertexbuffer object for the rendering program
	'''
    gl.glGenVertexArrays(1, ctypes.byref(render_vao))
    gl.glGenBuffers(1, ctypes.byref(render_vertexbuffer))

    loc_position = gl.glGetAttribLocation(
        render_program, ctypes.create_string_buffer(b'position'))
    loc_color = gl.glGetAttribLocation(render_program,
                                       ctypes.create_string_buffer(b'color'))

    if loc_position < 0:
        print('Warning: position is not used in the shader')
    if loc_color < 0:
        print('Warning: color is not used in the shader')

    gl.glBindVertexArray(render_vao)

    gl.glEnableVertexAttribArray(loc_position)
    gl.glEnableVertexAttribArray(loc_color)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer)

    gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False,
                             ctypes.sizeof(COLOR_VERTEX),
                             ctypes.c_void_p(COLOR_VERTEX.position.offset))
    gl.glVertexAttribPointer(loc_color, 4, gl.GL_FLOAT, False,
                             ctypes.sizeof(COLOR_VERTEX),
                             ctypes.c_void_p(COLOR_VERTEX.color.offset))

    gl.glBindVertexArray(0)
Beispiel #25
0
    def vertex_attrib(self, name, data, size=2, stride=0, offset=0):
        """
        Set vertex attribute data in a shader, lacks the flexibility of
        setting several attributes in one vertex buffer.

        Parameters
        ----------

        name: the attribute name in the shader.

        data: a list of vertex attributes (positions, colors, ...)

        Example: name = "positions", data = [0, 0, 0, 1, 1, 0, 1, 1].
        """
        data_ctype = (gl.GLfloat * len(data))(*data)

        vbo_id = gl.GLuint(0)
        gl.glGenBuffers(1, ct.byref(vbo_id))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype,
                        gl.GL_STATIC_DRAW)

        location = gl.glGetAttribLocation(self.program, name.encode("ascii"))
        gl.glEnableVertexAttribArray(location)
        gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE,
                                 stride, ct.c_void_p(offset))
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
        return vbo_id
Beispiel #26
0
    def on_draw(self):
        """
        Render the screen.
        """
        start = time.time()

        float_size = ctypes.sizeof(ctypes.c_float)
        record_len = 10 * float_size

        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        GL.glMatrixMode(GL.GL_MODELVIEW)
        GL.glEnableClientState(GL.GL_VERTEX_ARRAY)

        GL.glColor4ub(255, 0, 0, 255)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.rect_vbo.vbo_id)
        GL.glVertexPointer(2, GL.GL_FLOAT, record_len, 0)

        for i in range(len(self.shape_list)):
            shape = self.shape_list[i]
            GL.glLoadIdentity()
            GL.glTranslatef(shape.x, shape.y, 0)
            GL.glDrawArrays(GL.GL_QUADS, i * 8, 8)
        # GL.glDrawArrays(GL.GL_QUADS,
        #           0,
        #           self.rect_vbo.size)

        elapsed = time.time() - start
        print(elapsed)
Beispiel #27
0
def setup_copy_vertexbuffer():
    '''
	Create the vertexbuffer object for the copying program
	'''
    # gl.glGenVertexArrays(1, ctypes.byref(copy_vao))
    gl.glGenBuffers(1, ctypes.byref(copy_vertexbuffer))

    loc_position = gl.glGetAttribLocation(
        copy_program, ctypes.create_string_buffer(b'position'))
    loc_texcoord = gl.glGetAttribLocation(
        copy_program, ctypes.create_string_buffer(b'texcoord'))

    if loc_position < 0:
        print('Warning: position is not used in the shader')
    if loc_texcoord < 0:
        print('Warning: texcoord is not used in the shader')

    gl.glBindVertexArray(copy_vao)

    gl.glEnableVertexAttribArray(loc_position)
    gl.glEnableVertexAttribArray(loc_texcoord)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer)

    gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False,
                             ctypes.sizeof(TEXTURE_VERTEX),
                             ctypes.c_void_p(TEXTURE_VERTEX.position.offset))
    gl.glVertexAttribPointer(loc_texcoord, 2, gl.GL_FLOAT, False,
                             ctypes.sizeof(TEXTURE_VERTEX),
                             ctypes.c_void_p(TEXTURE_VERTEX.texcoord.offset))

    gl.glBindVertexArray(0)
    def __init__(
        self, ctx, data: Optional[Any] = None, reserve: int = 0, usage: str = "static"
    ):
        """
        :param Context ctx: The context this buffer belongs to
        :param Any data: The data this buffer should contain. It can be bytes or any object supporting the buffer protocol.
        :param int reserve: Create a buffer of a specific byte size
        :param str usage: A hit of this buffer is ``static`` or ``dynamic`` (can mostly be ignored)
        """
        self._ctx = ctx
        self._glo = glo = gl.GLuint()
        self._size = -1
        self._usage = Buffer._usages[usage]

        gl.glGenBuffers(1, byref(self._glo))
        # print(f"glGenBuffers() -> {self._glo.value}")
        if self._glo.value == 0:
            raise RuntimeError("Cannot create Buffer object.")

        # print(f"glBindBuffer({self._glo.value})")
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
        # print(f"glBufferData(gl.GL_ARRAY_BUFFER, {self._size}, data, {self._usage})")

        if data is not None and len(data) > 0:
            self._size, data = data_to_ctypes(data)
            gl.glBufferData(gl.GL_ARRAY_BUFFER, self._size, data, self._usage)
        elif reserve > 0:
            self._size = reserve
            gl.glBufferData(gl.GL_ARRAY_BUFFER, self._size, None, self._usage)
        else:
            raise ValueError("Buffer takes byte data or number of reserved bytes")

        self.ctx.stats.incr("buffer")
        weakref.finalize(self, Buffer.release, self.ctx, glo)
Beispiel #29
0
def render_to_texture():
    # select the target to draw into
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer)
    draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0)
    gl.glDrawBuffers(1, draw_buffers)
    gl.glViewport(0, 0, FB_WIDTH, FB_HEIGHT)

    # clear the destination
    gl.glClearColor(0.5, 0.6, 0.7, 1.0)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    # prepare the rendering
    gl.glUseProgram(render_program)

    # send the vertex data
    data = (COLOR_VERTEX * 3)(((-0.6, -0.5), (1.0, 0.0, 0.0, 1.0)),
                              ((0.6, -0.5), (0.0, 1.0, 0.0, 1.0)),
                              ((0.0, 0.5), (0.0, 0.0, 1.0, 1.0)))

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data,
                    gl.GL_DYNAMIC_DRAW)

    # draw using the vertex array for vertex information
    gl.glBindVertexArray(render_vao)
    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
    gl.glBindVertexArray(0)
Beispiel #30
0
def copy_texture_to_screen():
    # select the target to draw into
    gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
    gl.glViewport(0, 0, window.width, window.height)

    # clear the destination
    gl.glClearColor(0.4, 0.4, 0.4, 1.0)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

    # select the program for drawing
    gl.glUseProgram(copy_program)

    # send the vertex data
    data = (TEXTURE_VERTEX * 8)(
        ((-0.9, -0.9), (0.0, 0.0)),
        ((0.5, -0.9), (1.0, 0.0)),
        ((0.5, 0.5), (1.0, 1.0)),
        ((-0.9, 0.5), (0.0, 1.0)),
        ((0.6, 0.6), (0.0, 1.0)),
        ((1.0, 0.6), (1.0, 1.0)),
        ((1.0, 1.0), (1.0, 0.0)),
        ((0.6, 1.0), (0.0, 0.0)),
    )

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data,
                    gl.GL_DYNAMIC_DRAW)

    # draw
    gl.glBindVertexArray(copy_vao)
    gl.glDrawArrays(gl.GL_QUADS, 0, 8)
    gl.glBindVertexArray(0)
def create_line_generic(draw_type: int,
                        point_list: PointList,
                        color: Color, line_width: float=1):
    """
    This function is used by ``create_line_strip`` and ``create_line_loop``,
    just changing the OpenGL type for the line drawing.
    """
    data = []
    for point in point_list:
        data.append(point[0])
        data.append(point[1])

    vbo_id = gl.GLuint()

    gl.glGenBuffers(1, ctypes.pointer(vbo_id))

    # Create a buffer with the data
    # This line of code is a bit strange.
    # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number
    # (*data) initalizes the list with the floats. *data turns the list into a
    # tuple.
    data2 = (gl.GLfloat * len(data))(*data)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    gl.GL_STATIC_DRAW)

    shape = VertexBuffer(vbo_id, len(data) // 2, draw_type)

    shape.color = color
    shape.line_width = line_width
    return shape
Beispiel #32
0
    def draw(self):
        '''
        Draw the windows.
        '''
        self.program.use()

        data = list(self.root.get_data(0, 0))
        data = (gl.GLfloat * len(data))(*data)

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer)
        gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_DYNAMIC_DRAW)

        gl.glActiveTexture(gl.GL_TEXTURE0)
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture)
        if self.textmanager.dirty:
            # only upload the texture to the GPU if it has actually changed
            gl.glTexImage2D(gl.GL_TEXTURE_2D,
                     0,  # level
                     gl.GL_R8,
                     self.textmanager.width,
                     self.textmanager.height,
                     0,
                     gl.GL_RED,
                     gl.GL_UNSIGNED_BYTE,
                     ctypes.create_string_buffer(self.textmanager.img.tobytes()))
            self.textmanager.dirty = False
        self.program.uniform1i(b"tex", 0)  # set to 0 because the texture is bound to GL_TEXTURE0

        self.program.vertex_attrib_pointer(self.buffer, b"position", 4)
        # self.program.vertex_attrib_pointer(self.buffer, b"texcoord", 2, stride=4 * sizeof(gl.GLfloat), offset=2 * sizeof(gl.GLfloat))
        gl.glDrawArrays(gl.GL_QUADS, 0, len(data) // 4)
Beispiel #33
0
    def _set_points(self, points, kind, tris):
        """Helper to set fill and line points"""
        from pyglet import gl

        if points is None:
            self._counts[kind] = 0
        points = np.asarray(points, dtype=np.float32, order='C')
        assert points.ndim == 2 and points.shape[1] == 2
        array_count = points.size // 2 if kind == 'line' else points.size
        if kind == 'fill':
            assert tris is not None
            tris = np.asarray(tris, dtype=np.uint32, order='C')
            assert tris.ndim == 1 and tris.size % 3 == 0
            tris.shape = (-1, 3)
            assert (tris < len(points)).all()
            self._tris[kind] = tris
            del tris
        self._points[kind] = points
        del points

        gl.glUseProgram(self._program)
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._buffers[kind]['array'])
        gl.glBufferData(gl.GL_ARRAY_BUFFER, self._points[kind].size * 4,
                        self._points[kind].tostring(), gl.GL_STATIC_DRAW)
        if kind == 'line':
            self._counts[kind] = array_count
        if kind == 'fill':
            self._counts[kind] = self._tris[kind].size
            gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER,
                            self._buffers[kind]['index'])
            gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER,
                            self._tris[kind].size * 4,
                            self._tris[kind].tostring(), gl.GL_STATIC_DRAW)
        gl.glUseProgram(0)
Beispiel #34
0
def create_ellipse(width, height, color):
    """
    This creates an ellipse vertex buffer object (VBO). It can later be
    drawn with ``render_ellipse_filled``. This method of drawing an ellipse
    is much faster than calling ``draw_ellipse_filled`` each frame.
    """
    num_segments = 64

    data = []

    for i in range(num_segments + 1):
        theta = 2.0 * 3.1415926 * i / num_segments

        x = width * math.cos(theta)
        y = height * math.sin(theta)

        data.extend([x, y])

    vbo_id = GL.GLuint()

    GL.glGenBuffers(1, ctypes.pointer(vbo_id))

    v2f = data
    data2 = (GL.GLfloat*len(v2f))(*v2f)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)

    shape = VertexBuffer(vbo_id, len(v2f)//2, width, height, color)
    return shape
Beispiel #35
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)
Beispiel #36
0
def upload_indices(asset: ModelAsset, gl_usage=GL_STATIC_DRAW):
    for buffer in asset.index_buffers:
        # noinspection PyCallingNonCallable,PyTypeChecker
        index_data_gl = (GLint * len(buffer.indices))(*buffer.indices)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.id)
        index_buffer_size = sizeof(index_data_gl)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, index_data_gl,
                     gl_usage)
Beispiel #37
0
 def __init__(self, type, data):
     self.type = type
     self.data = data
     self.id = gl.GLuint()
     gl.glGenBuffers(1, ctypes.pointer(self.id))
     self.data_ptr = (gl.GLfloat * len(data))(*data)
     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.id)
     gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(self.data_ptr), self.data_ptr, gl.GL_STATIC_DRAW)
Beispiel #38
0
    def _read(self, size):
        """ Debug method to read data from the buffer. """

        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer_id)
        ptr = gl.glMapBufferRange(gl.GL_ARRAY_BUFFER, gl.GLintptr(0), size,
                                  gl.GL_MAP_READ_BIT)
        print(f"Reading back from buffer:\n{string_at(ptr, size=size)}")
        gl.glUnmapBuffer(gl.GL_ARRAY_BUFFER)
Beispiel #39
0
def createVertexbuffer(vertexData,
                       vertexSize=3,
                       bufferType=GL.GL_VERTEX_ARRAY):
    """Create a static, single-storage Vertex Buffer Object (VBO).

    Parameters
    ----------
    vertexData : :obj:`list` or :obj:`tuple` of :obj:`float`
        Coordinates as a 1D array of floats (e.g. [X0, Y0, Z0, X1, Y1, Z1, ...])
    vertexSize : :obj:`int`
        Number of coordinates per-vertex, default is 3.
    bufferType : :obj:`int`
        The type of data stored in the buffer (e.g. GL_VERTEX_ARRAY,
        GL_TEXTURE_COORD_ARRAY, GL_NORMAL_ARRAY, etc.)

    Returns
    -------
    Vertexbuffer
        A descriptor with vertex buffer information.

    Examples
    --------
    # vertices of a triangle
    verts = [ 1.0,  1.0, 0.0,   # v0
              0.0, -1.0, 0.0,   # v1
             -1.0,  1.0, 0.0]   # v2

    # load vertices to graphics device, return a descriptor
    vboDesc = createVertexbuffer(verts, 3)

    # draw
    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vboDesc.id)
    GL.glVertexPointer(vboDesc.vertexSize, vboDesc.dtype, 0, None)
    GL.glEnableClientState(vboDesc.bufferType)
    GL.glDrawArrays(GL.GL_TRIANGLES, 0, vboDesc.indices)
    GL.glFlush()

    """
    # convert values to ctypes float array
    count = len(vertexData)
    c_array = (GL.GLfloat * count)(*vertexData)

    # create a vertex buffer ID
    vboId = GL.GLuint()
    GL.glGenBuffers(1, ctypes.byref(vboId))

    # new vertex descriptor
    vboDesc = Vertexbuffer(vboId, vertexSize, count, int(count / vertexSize),
                           GL.GL_STATIC_DRAW, bufferType,
                           GL.GL_FLOAT)  # always float

    # bind and upload
    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(c_array), c_array,
                    GL.GL_STATIC_DRAW)
    # GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)

    return vboDesc
Beispiel #40
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)
Beispiel #41
0
def _set_vbo(vbo_id, points):
    """
    Given a vertex buffer id, this sets the vertexes to be
    part of that buffer.
    """
    data2 = (GL.GLfloat * len(points))(*points)
    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)
def stripped_render(shape: VertexBuffer):
    """
    Render an shape previously created with a ``create`` function.
    Used by ``ShapeElementList.draw()`` for drawing several shapes in a batch.
    """

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, shape.vbo_vertex_id)
    gl.glVertexPointer(2, gl.GL_FLOAT, 0, 0)
    gl.glDrawArrays(shape.draw_mode, 0, shape.size)
Beispiel #43
0
 def vertex_attrib_pointer(self, buffer, name, size, type=gl.GL_FLOAT, normalized=False, stride=0, offset=0):
     self.use()
     loc = gl.glGetAttribLocation(self.handle, ctypes.create_string_buffer(name))
     if loc < 0:
         logging.warning('Attribute {} is not in the shader.'.format(name))
         return
     gl.glEnableVertexAttribArray(loc)
     gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buffer)
     gl.glVertexAttribPointer(loc, size, type, normalized, stride, ctypes.c_void_p(offset))
    def write(self, data: Any, offset: int = 0):
        """Write byte data to the buffer.

        :param bytes data: The byte data to write. This can be bytes or any object supporting the buffer protocol.
        :param int offset: The byte offset
        """
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
        size, data = data_to_ctypes(data)
        gl.glBufferSubData(gl.GL_ARRAY_BUFFER, gl.GLintptr(offset), size, data)
Beispiel #45
0
  def __set_attributes(self):
    if self.__vao is None:
      self.__vao = util.vertex_array()
    gl.glBindVertexArray(self.__vao.value)

    # coord
    coord_loc = gl.glGetAttribLocation(self.__prog.value, "coord")
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.__geom_buffer.value)
    gl.glVertexAttribPointer(coord_loc, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0)
    gl.glEnableVertexAttribArray(coord_loc)
Beispiel #46
0
def _set_vbo(vbo_id: gl.GLuint, points: List[float]):
    """
    Given a vertex buffer id, this sets the vertexes to be
    part of that buffer.
    """

    # todo what does it do?
    data2 = (gl.GLfloat*len(points))(*points)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    gl.GL_STATIC_DRAW)
Beispiel #47
0
 def __alloc(cls, target, format, usage): 
     buf = super().__new__(cls)
     buf.owned = True
     buf.bid = GLuint()
     glGenBuffers(1, byref(buf.bid))
     glBindBuffer(target, buf.bid)
     buf._usage = usage
     buf.format = BufferFormat.new(format)
     buf.target = target
     buf.mapinfo = None
     
     return buf
Beispiel #48
0
def create_vbo_for_rects(v2f):
    vbo_id = GL.GLuint()

    GL.glGenBuffers(1, ctypes.pointer(vbo_id))

    data2 = (GL.GLfloat*len(v2f))(*v2f)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)

    shape = VertexBuffer(vbo_id, len(v2f)//2)
    return shape
Beispiel #49
0
def render_rect_filled(shape, x, y):
    """ Render the shape at the right spot. """
    # Set color
    GL.glDisable(GL.GL_BLEND)
    GL.glColor4ub(shape.color[0], shape.color[1], shape.color[2], 255)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, shape.vbo_id)
    GL.glVertexPointer(2, GL.GL_FLOAT, 0, 0)

    GL.glLoadIdentity()
    GL.glTranslatef(x + shape.width / 2, y + shape.height / 2, 0)

    GL.glDrawArrays(GL.GL_QUADS, 0, shape.size)
Beispiel #50
0
 def bind(self, target=None):
     """
         Bind the buffer to its target
     
         Arguments:
             target: Default to None. One of the GL target (such as GL_ARRAY_BUFFER)
                     If None, use the default buffer target.
     """
     if self.target is None:
         raise ValueError("Buffer target was not defined")
         
     target = target if target is not None else self.target
     glBindBuffer(target, self.bid)
Beispiel #51
0
def create_rect(width, height, color):
    """ Create a vertex buffer for a rectangle. """
    v2f = [-width / 2, -height / 2,
           width / 2, -height / 2,
           width / 2, height / 2,
           -width / 2, height / 2]

    vbo_id = GL.GLuint()

    GL.glGenBuffers(1, ctypes.pointer(vbo_id))

    data2 = (GL.GLfloat*len(v2f))(*v2f)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)

    shape = VertexBuffer(vbo_id, len(v2f)//2, width, height, color)
    return shape
Beispiel #52
0
def create_colors(rect_list):
    """ Create a vertex buffer for a set of rectangles. """

    v2f = []
    for shape in rect_list:
        for i in range(4):
            v2f.extend(shape.color)

    vbo_id = GL.GLuint()

    GL.glGenBuffers(1, ctypes.pointer(vbo_id))

    data2 = (GL.GLfloat*len(v2f))(*v2f)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)

    return vbo_id
Beispiel #53
0
  def __setup_data_buffer(self):
    data_ptr = ct.cast( np.ctypeslib.as_ctypes(self.__data),
        ct.POINTER(ct.c_float) )

    self.__data_buffer = util.buffer()
    gl.glBindBuffer(gl.GL_TEXTURE_BUFFER, self.__data_buffer.value)
    gl.glBufferData(gl.GL_TEXTURE_BUFFER, 
        ct.sizeof(ct.c_float)*self.__data.size,
        data_ptr,
        gl.GL_STATIC_DRAW)

    if self.__data_texture is None:
      self.__data_texture = util.texture()
    gl.glActiveTexture(gl.GL_TEXTURE0)
    gl.glBindTexture(gl.GL_TEXTURE_BUFFER, self.__data_texture.value)

    gl.glTexBuffer(gl.GL_TEXTURE_BUFFER, gl.GL_R32F, 
        self.__data_buffer.value)

    self.__data_altered = False
Beispiel #54
0
def _draw_rects(shape_list: Iterable[Sprite], vertex_vbo_id: gl.GLuint,
                texture_coord_vbo_id: gl.GLuint):
    """
    Draw a set of rectangles using vertex buffers. This is more efficient
    than drawing them individually.
    """
    gl.glEnable(gl.GL_BLEND)
    gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
    gl.glEnable(gl.GL_TEXTURE_2D) # As soon as this happens, can't use drawing commands
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE)
    gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)
    gl.glHint(gl.GL_POLYGON_SMOOTH_HINT, gl.GL_NICEST)
    gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST)

    # gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
    # gl.glMatrixMode(gl.GL_MODELVIEW)
    # gl.glDisable(gl.GL_BLEND)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vertex_vbo_id)
    gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY)
    gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
    gl.glVertexPointer(2, gl.GL_FLOAT, 0, 0)

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, texture_coord_vbo_id)

    offset = 0
    for shape in shape_list:
        if shape.can_cache:
            texture_coord_vbo_id = None

            gl.glColor4f(1, 1, 1, shape.alpha)

            _render_rect_filled(shape, offset,
                                shape.texture.texture_id, texture_coord_vbo_id)

            offset += 4
        else:
            shape.draw()
    gl.glDisable(gl.GL_TEXTURE_2D)
Beispiel #55
0
def create_rects(rect_list):
    """ Create a vertex buffer for a set of rectangles. """

    v2f = []
    for shape in rect_list:
        v2f.extend([-shape.width / 2, -shape.height / 2,
                   shape.width / 2, -shape.height / 2,
                   shape.width / 2, shape.height / 2,
                   -shape.width / 2, shape.height / 2])

    vbo_id = GL.GLuint()

    GL.glGenBuffers(1, ctypes.pointer(vbo_id))

    data2 = (GL.GLfloat*len(v2f))(*v2f)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id)
    GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2,
                    GL.GL_STATIC_DRAW)

    shape = VertexBuffer(vbo_id, len(v2f)//2)
    return shape
Beispiel #56
0
 def map(self, access=GL_READ_WRITE, target=None):
     """
     Map the buffer locally. This increase the reading/writing speed.
     If the buffer was already mapped, a BufferError will be raised.
     
     Arguments:
         access: Buffer access. Can be GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY. Default to GL_READ_WRITE
         target: Target to bind the buffer to. If None, use the buffer default target. Default to None.
     """
     if self.mapped == GL_TRUE:
         raise BufferError("Buffer is already mapped")
     
     target = target if target is not None else self.target
     glBindBuffer(target, self.bid)
     glMapBuffer(target, access)
     
     ptr_type = POINTER(self.format.struct)
     ptr = c_void_p()
     glGetBufferPointerv(target, GL_BUFFER_MAP_POINTER, byref(ptr))        
     
     self.mapinfo = map_info(target=target, access=access, ptr=cast(ptr,ptr_type),
                             size=self.size//sizeof(self.format.struct))
Beispiel #57
0
def render_rectangle_filled(shape, center_x, center_y, color, tilt_angle=0):
    """
    Render a rectangle previously created by the ``create_rectangle`` command.
    """
    # Set color
    if len(color) == 4:
        GL.glColor4ub(shape.color[0], shape.color[1], shape.color[2],
                      shape.color[3])
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
    elif len(color) == 3:
        GL.glDisable(GL.GL_BLEND)
        GL.glColor4ub(shape.color[0], shape.color[1], shape.color[2], 255)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, shape.vbo_id)
    GL.glVertexPointer(2, GL.GL_FLOAT, 0, 0)

    GL.glLoadIdentity()
    GL.glTranslatef(center_x + shape.width / 2, center_y + shape.height / 2, 0)
    if tilt_angle != 0:
        GL.glRotatef(tilt_angle, 0, 0, 1)

    GL.glDrawArrays(GL.GL_QUADS, 0, shape.size)
Beispiel #58
0
def render_ellipse_filled(shape, center_x, center_y, color, angle=0):
    """
    Render an ellipse previously created with the ``create_ellipse`` function.
    """
    # Set color
    if len(color) == 4:
        GL.glColor4ub(shape.color[0], shape.color[1], shape.color[2],
                      shape.color[3])
        GL.glEnable(GL.GL_BLEND)
        GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
    elif len(color) == 3:
        GL.glDisable(GL.GL_BLEND)
        GL.glColor4ub(shape.color[0], shape.color[1], shape.color[2], 255)

    GL.glBindBuffer(GL.GL_ARRAY_BUFFER, shape.vbo_id)
    GL.glVertexPointer(2, GL.GL_FLOAT, 0, 0)

    GL.glLoadIdentity()
    GL.glTranslatef(center_x, center_y, 0)
    if angle:
        GL.glRotatef(angle, 0, 0, 1)

    GL.glDrawArrays(GL.GL_TRIANGLE_FAN, 0, shape.size)
Beispiel #59
0
  def __setup_geometry_buffer(self):
    data_buffer = ((ct.c_float*3)*36)()
    # {{{ vertex data for cube
    v0 = ( .5, .5, .5 )
    v1 = ( -.5, .5, .5 )
    v2 = ( -.5, -.5, .5 )
    v3 = ( .5, -.5, .5 )
    v4 = ( .5, .5, -.5 )
    v5 = ( -.5, .5, -.5 )
    v6 = ( -.5, -.5, -.5 )
    v7 = ( .5, -.5, -.5 )

    data_buffer[0:3] = (v4, v0, v7)
    data_buffer[3:6] = (v0, v3, v7)
    data_buffer[6:9] = (v0, v1, v2)
    data_buffer[9:12] = (v0, v2, v3)
    data_buffer[12:15] = (v5, v1, v0)
    data_buffer[15:18] = (v5, v0, v4)
    data_buffer[18:21] = (v3, v6, v7)
    data_buffer[21:24] = (v3, v2, v6)
    data_buffer[24:27] = (v2, v1, v6)
    data_buffer[27:30] = (v6, v1, v5)
    data_buffer[30:33] = (v4, v6, v5)
    data_buffer[33:36] = (v7, v6, v4)
    # }}}

    data_ptr = ct.cast(ct.pointer(data_buffer),
        ct.POINTER(ct.c_float))

    # create GL buffer
    self.__geom_buffer = util.buffer()
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.__geom_buffer.value)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_buffer),
        data_ptr,
        gl.GL_STATIC_DRAW)
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)