Example #1
0
    def from_matrix(cls, matrix):
        """Creates a texture from given matrix file.

        :param matrix: The matrix.
        :type matrix: list

        :returns: The texture instance.
        :rtype: :class:`renderer.Texture`
        """
        w, h = len(matrix[0]), len(matrix)

        grid = bytes(chain.from_iterable(reversed(matrix)))

        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)

        # This code is necessary to handle non-power-of-two textures with small
        # sizes.
        # TODO: refactor this
        param_ids = [
            GL_UNPACK_ALIGNMENT,
            GL_UNPACK_ROW_LENGTH,
            GL_UNPACK_SKIP_ROWS,
            GL_UNPACK_SKIP_PIXELS,
        ]
        old_params = {
            p: glGetInteger(p)
            for p in param_ids
        }

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
        glPixelStorei(GL_UNPACK_SKIP_ROWS, 0)
        glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, w, h)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RED, GL_UNSIGNED_BYTE, grid)

        for p, v in old_params.items():
            glPixelStorei(p, v)

        glBindTexture(GL_TEXTURE_2D, 0)

        return Texture(tex, w, h, GL_TEXTURE_2D)
Example #2
0
    def render_to_texture(self, text):
        """Renders the given string to a texture object.

        :param text: Text to render.
        :type text: str

        :returns: The resulting texture object.
        :rtype: :class:`renderer.Texture`
        """
        # render the text to a SDL_Surface structure
        surf_ptr = ttf.TTF_RenderText_Solid(
            self.font,
            text.encode('utf8'),
            sdl.SDL_Color())
        if not surf_ptr:
            raise SDLError('failed to render text to surface: {}'.format(
                ttf.TTF_GetError()))

        # retrieve a pointer to pixel data
        surf = surf_ptr.contents
        pixels = ctypes.cast(surf.pixels, ctypes.POINTER(ctypes.c_char))

        # create and fill an OpenGL rectangle texture (that is, a texture which
        # can have arbitrary non-power-of-two size and is accessed using
        # UV coordinates which are linearly mapped to the texture size)
        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, surf.w, surf.h)
        glTexSubImage2D(
            GL_TEXTURE_2D,
            0,
            0,
            0,
            surf.w,
            surf.h,
            GL_RED,
            GL_UNSIGNED_BYTE,
            pixels)
        glBindTexture(GL_TEXTURE_2D, 0)

        sdl.SDL_FreeSurface(surf_ptr)

        return Texture(tex, surf.w, surf.h, GL_TEXTURE_2D)
Example #3
0
    def from_image(cls, image):
        """Creates a texture from given image file.

        :param image: Image.
        :type image: :class:`PIL.Image`

        :returns: The texture instance.
        :rtype: :class:`renderer.Texture`
        """
        w, h = image.size

        tex = glGenTextures(1)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, w, h)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGB, GL_UNSIGNED_BYTE, image.tobytes())
        glBindTexture(GL_TEXTURE_2D, 0)

        return Texture(tex, w, h)