Example #1
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)
Example #2
0
    def _build(self, program: Program, content: Sequence[BufferDescription],
               index_buffer):
        """Build a vertex array compatible with the program passed in"""
        gl.glGenVertexArrays(1, byref(self.glo))
        gl.glBindVertexArray(self.glo)

        # Lookup dict for BufferDescription attrib names
        # print(content)
        descr_attribs = {
            attr.name: (descr, attr)
            for descr in content for attr in descr.formats
        }
        # print('->', descr_attribs)

        # Build the vao according to the shader's attribute specifications
        for i, prog_attr in enumerate(program.attributes):
            # print('prog_attr', prog_attr)
            # Do we actually have an attribute with this name in buffer descriptions?
            if prog_attr.name.startswith("gl_"):
                continue
            try:
                buff_descr, attr_descr = descr_attribs[prog_attr.name]
            except KeyError:
                raise ValueError((
                    f"Program needs attribute '{prog_attr.name}', but is not present in buffer description. "
                    f"Buffer descriptions: {content}"))

            # TODO: Sanity check this
            # if buff_descr.instanced and i == 0:
            #     raise ValueError("The first vertex attribute cannot be a per instance attribute.")

            # Make sure components described in BufferDescription and in the shader match
            if prog_attr.components != attr_descr.components:
                raise ValueError((
                    f"Program attribute '{prog_attr.name}' has {prog_attr.components} components "
                    f"while the buffer description has {attr_descr.components} components. "
                ))

            # TODO: Compare gltype between buffer descr and program attr

            gl.glEnableVertexAttribArray(prog_attr.location)
            gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buff_descr.buffer.glo)

            # TODO: Detect normalization
            normalized = (gl.GL_TRUE if attr_descr.name
                          in buff_descr.normalized else gl.GL_FALSE)
            gl.glVertexAttribPointer(
                prog_attr.location,  # attrib location
                attr_descr.components,  # 1, 2, 3 or 4
                attr_descr.gl_type,  # GL_FLOAT etc
                normalized,  # normalize
                buff_descr.stride,
                c_void_p(attr_descr.offset),
            )
            # print((
            #     f"gl.glVertexAttribPointer(\n"
            #     f"    {prog_attr.location},  # attrib location\n"
            #     f"    {attr_descr.components},  # 1, 2, 3 or 4\n"
            #     f"    {attr_descr.gl_type},  # GL_FLOAT etc\n"
            #     f"    {normalized},  # normalize\n"
            #     f"    {buff_descr.stride},\n"
            #     f"    c_void_p({attr_descr.offset}),\n"
            # ))
            # TODO: Sanity check this
            if buff_descr.instanced:
                gl.glVertexAttribDivisor(prog_attr.location, 1)

        if index_buffer is not None:
            gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, index_buffer.glo)
Example #3
0
        def construct_offset_buffer():
            gl.glBufferData(gl.GL_ARRAY_BUFFER, 9 * 2 * sizeof(gl.GLfloat), None, gl.GL_DYNAMIC_DRAW)

            gl.glEnableVertexAttribArray(1)
            gl.glVertexAttribPointer(1, 2, gl.GL_FLOAT, False, 2 * sizeof(gl.GLfloat), 0)
            gl.glVertexAttribDivisor(1, 1)