Пример #1
0
    def convert_png_to_jpg_rgb(self, tex_path):
        tex_basename = os.path.splitext(tex_path)[0]
        img = PNMImage()
        self.load_img_with_retry(img, tex_path)

        jpg_path = tex_basename + '.jpg'

        x_size = img.get_x_size()
        y_size = img.get_y_size()
        output_img = PNMImage(x_size, y_size, 3)
        output_img.copy_sub_image(img, 0, 0, 0, 0, x_size, y_size)

        jpg_path = tex_basename + '.jpg'

        print(f'Writing JPG {jpg_path}...')
        output_img.write(Filename.from_os_specific(jpg_path))

        if img.num_channels == 4:
            alpha_image = PNMImage(x_size, y_size, 1)
            alpha_image.set_type(RGB_TYPE)

            # Copy alpha channel from source image
            for i in range(x_size):
                for j in range(y_size):
                    alpha_image.set_gray(i, j, img.get_alpha(i, j))

            rgb_path = tex_basename + '_a.rgb'

            print(f'Writing RGB {rgb_path}...')
            alpha_image.write(Filename.from_os_specific(rgb_path))
Пример #2
0
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    from panda3d.core import Filename
    shaders = Shader.load(Shader.SL_GLSL,
                          Filename('Shader/Star/vertex.glsl'),
                          Filename('Shader/Star/fragment.glsl'),
                          Filename(''),
                          Filename(''),
                          Filename(''))
    if not shaders:
        print("WARNING. STAR SHADER FAILED TO LOAD", type(shaders))
    else:
        final_node_path.set_shader_input('cameraSpherePos', 1, 1, 1)
        final_node_path.set_shader_input('sphereRadius', 1.0)
        final_node_path.set_shader_input('myCamera', base.camera)
        final_node_path.set_shader(shaders)
        final_node_path.set_shader_input('blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = sandbox.base.loader.loadTexture('data/empty_textures/empty_normal.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = sandbox.base.loader.loadTexture('data/empty_textures/empty_specular.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = sandbox.base.loader.loadTexture('data/empty_textures/empty_roughness.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Пример #3
0
    def create_stray_texture(self, texture_img, create_rgb=True):
        """
        Converts a TextureImage into actual PNMImages.
        Creates an RGB version of the texture if requested.
            :texture_img: The TextureImage you want to process.
            :create_rgb: Would you like to create an RGB variant of the texture? True by default.
        """
        if not texture_img.dest_ids:
            # This texture image is not a stray image.
            return

        source = texture_img.sources[0]
        dest = texture_img.dests[0]

        # Extrapolate the phase folder from the first assigned group
        phase_folder = texture_img.actual_assigned_groups.groups[0].dirname

        # Extrapolate the base name from the destination image
        basename = os.path.splitext(os.path.basename(dest.filename))[0]

        # Is this an RGB only texture?
        # Some textures, like fonts, are saved as grayscale RGB.
        rgb_only = texture_img.properties.format == TextureGlobals.F_alpha

        # Read the texture from Pandora!
        image = self.read_texture(source.filename)

        # Let's save the texture as a power of two resolution.
        x_size, y_size = self.scale_power_of_2(image.get_x_size(),
                                               image.get_y_size())

        alpha_image = None

        # Resize our image to the desired size.
        image = self.resize_image(image, x_size, y_size)
        has_alpha = source.properties.effective_channels in (2, 4)

        if dest.alpha_filename and has_alpha and create_rgb and not rgb_only:
            alpha_image = PNMImage(x_size, y_size, 1)
            alpha_image.set_type(PalettizeGlobals.RGB_TYPE)

            # Copy alpha channel from source image
            for i in range(x_size):
                for j in range(y_size):
                    alpha_image.set_gray(i, j, image.get_alpha(i, j))

        return image, alpha_image, has_alpha, phase_folder, basename, rgb_only
Пример #4
0
def make_star(name='star', scale=1, color=Vec3(1), texture_size=64, debug=False):
    card_maker = CardMaker(name)
    card_maker.set_frame(-1, 1, -1, 1)
    node_path = NodePath(name)
    node = card_maker.generate()
    final_node_path = node_path.attach_new_node(node)
    final_node_path.set_billboard_point_eye()
    shaders = Shader.load(Shader.SLGLSL,
                          'Shader/Star/vertex.glsl',
                          'Shader/Star/fragment.glsl')
    final_node_path.set_shader_input(b'cameraSpherePos', 1, 1, 1)
    final_node_path.set_shader_input(b'sphereRadius', 1.0)
    final_node_path.set_shader_input(b'myCamera', base.camera)
    final_node_path.set_shader(shaders)
    final_node_path.set_shader_input(b'blackbody', color)
    material = Material()
    material.set_emission(VBase4(color, 1.0))
    final_node_path.set_material(material)
    xn = PerlinNoise3(0.5, 0.5, 0.5)
    #yn = PerlinNoise3(0.5, 0.5, 0.5)
    texture = Texture('star')
    texture.setup_3d_texture()
    for z in range(texture_size):
        p = PNMImage(texture_size, texture_size)
        for y in range(texture_size):
            for x in range(texture_size):
                p.set_gray(x, y, abs(xn.noise(x, y, z)))
        texture.load(p, z, 0)
    diffuse = texture
    diffuse.setMinfilter(Texture.FTLinearMipmapLinear)
    diffuse.setAnisotropicDegree(4)
    final_node_path.set_texture(diffuse)
    normal = base.loader.loadTexture('Data/Textures/EmptyNormalTexture.png')
    normalts = TextureStage('normalts')
    final_node_path.set_texture(normalts, normal)
    specular = base.loader.loadTexture('Data/Textures/EmptySpecularTexture.png')
    spects = TextureStage('spects')
    final_node_path.set_texture(spects, specular)
    roughness = base.loader.loadTexture('Data/Textures/EmptyRoughnessTexture.png')
    roughts= TextureStage('roughts')
    final_node_path.set_texture(roughts, roughness)
    return final_node_path
Пример #5
0
    def palettize(self, palette_img, create_rgb=True):
        """
        Runs all palettization procedures on the given PaletteImage.
        Creates an RGB version of the palette if requested.
            :palette_img: The PaletteImage you want to palettize.
            :create_rgb: Would you like to create an RGB variant of the palette? True by default.
        """
        # We need to know the palette's prior size
        if not palette_img.size_known:
            raise PalettizerException(
                "Palette image's size is not known, this is a fatal error!")

        palette_name = palette_img.basename

        if self.debug:
            print(
                f'[{palette_img.page.group.dirname}] Compiling {palette_name}..'
            )

        # Our max distortion is 1, as we do not want to resize the palette to be smaller accidentally
        max_distortion = 1

        # This array holds all of our PNMImage source textures
        imgs = []

        # We're going to check all of the source textures
        # so that we can load all of them and determine our palette's final size
        for placement in palette_img.placements:
            sources = placement.texture.sources

            # We need to know the size of all source textures
            # If a source texture's size is not known, that means that it has been defined but did not exist on the disk when creating textures.boo
            for source in sources:
                if not source.size_known:
                    print(
                        f'Warning: Size is not known for source {source.filename}, please consider fixing the texture path and re-running egg-palettize'
                    )

            # Source (original) full resolution texture size
            source = sources[0]
            x_size = source.x_size
            y_size = source.y_size

            # Prior texture position and size
            tex_position = placement.position
            tex_x_size = tex_position.x_size
            tex_y_size = tex_position.y_size

            # DISTORTER
            # Fold the points until they scream out
            # DISTORTER
            # Change the way it sounds

            # We need to calculate the maximum distortion for both our X and Y (U/V) coordinates
            if x_size != tex_x_size:
                x_distortion = x_size / tex_x_size

                if x_distortion > max_distortion:
                    max_distortion = x_distortion

            if y_size != tex_y_size:
                y_distortion = y_size / tex_y_size

                if y_distortion > max_distortion:
                    max_distortion = y_distortion

            # If we have more than one source, that means our texture
            # has been defined multiple times for the same group...
            # Panda3D uses the first source texture only, so that's what we'll do.
            # But we'll make sure to print a warning either way!
            if len(sources) > 1:
                source2 = sources[1]

                if source2.x_size != x_size or source2.y_size != y_size:
                    print(
                        f'Two different source textures are defined for {palette_name}: {source.filename} ({x_size} {y_size}) vs {source2.filename} ({source2.x_size} {source2.y_size})'
                    )

            # Time to load the source file from Pandora!
            img = self.read_texture(source.filename)

            # Add the source image to our list
            imgs.append(img)

        # Well, time to calculate the palette's final size!
        # We will multiply the current size with the highest distortion.
        # We do NOT calculate X and Y distortion separately.
        # Doing so would destroy the aspect ratio of the palette.
        current_x_size = palette_img.x_size
        current_y_size = palette_img.y_size
        new_x_size = round(current_x_size * max_distortion)
        new_y_size = round(current_y_size * max_distortion)

        # Power of two time!
        # It's easier for the game engine to load, as it does not have to scale it automatically.
        new_x_size, new_y_size = self.scale_power_of_2(new_x_size, new_y_size)

        # We've changed the palette size. It is necessary to recalculate our texture distortion.
        x_distortion = new_x_size / current_x_size
        y_distortion = new_y_size / current_y_size

        # Create our palette image with four channels.
        # We will cut down the last channel when necessary.
        # Having a fourth, empty channel would only increase the file size.
        new_image = PNMImage(new_x_size, new_y_size, 4)
        new_image.alpha_fill(1)

        # Textures with alpha always have four channels set (three for RGB and one for Alpha).
        has_alpha = palette_img.properties.effective_channels in (2, 4)
        rgb_only = palette_img.properties.format == TextureGlobals.F_alpha
        alpha_image = None

        # If necessary and possible, create an alpha image as well.
        # Textures with alpha always have four channels set (three for RGB and one for Alpha).
        if create_rgb and has_alpha and not rgb_only:
            alpha_image = PNMImage(new_x_size, new_y_size, 1)
            alpha_image.set_type(PalettizeGlobals.RGB_TYPE)

        for i, placement in enumerate(palette_img.placements):
            # Find the loaded source image from before...
            texture_img = imgs[i]

            # Calculate the placement of our image!
            tex_position = placement.placed

            # Determine the upper left and lower right corners
            # with some matrix magic.
            transform = placement.compute_tex_matrix()
            ul = transform.xform_point(LTexCoordd(0.0, 1.0))
            lr = transform.xform_point(LTexCoordd(1.0, 0.0))

            # Calculate the top, left, bottom and right corners.
            top = int(math.floor((1.0 - ul[1]) * new_y_size + 0.5))
            left = int(math.floor(ul[0] * new_x_size + 0.5))
            bottom = int(math.floor((1.0 - lr[1]) * new_y_size + 0.5))
            right = int(math.floor(lr[0] * new_x_size + 0.5))

            tex_x_size = right - left
            tex_y_size = bottom - top
            org_x_size = round(tex_position.x_size * x_distortion)
            org_y_size = round(tex_position.y_size * y_distortion)
            tex_x = round(tex_position.x * x_distortion)
            tex_y = round(tex_position.y * y_distortion)

            # Resize our image to the desired size.
            texture_img = self.resize_image(texture_img, tex_x_size,
                                            tex_y_size)

            for y in range(tex_y, tex_y + org_y_size):
                sy = y - top

                # UV wrapping modes - V component (for Y texture coordinate)
                if placement.placed.wrap_v == TextureGlobals.WM_clamp:
                    sy = max(min(sy, tex_y_size - 1), 0)
                elif placement.placed.wrap_v == TextureGlobals.WM_mirror:
                    sy = (tex_y_size * 2) - 1 - (
                        (-sy - 1) %
                        (tex_y_size * 2)) if sy < 0 else sy % (tex_y_size * 2)
                    sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1
                elif placement.placed.wrap_v == TextureGlobals.WM_mirror_once:
                    sy = sy if sy < tex_y_size else 2 * tex_y_size - sy - 1

                    # Repeat texture
                    sy = tex_y_size - 1 - (
                        (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size
                elif placement.placed.wrap_v == TextureGlobals.WM_border_color:
                    if sy < 0 or sy >= tex_y_size:
                        continue
                else:
                    # Repeat texture
                    sy = tex_y_size - 1 - (
                        (-sy - 1) % tex_y_size) if sy < 0 else sy % tex_y_size

                for x in range(tex_x, tex_x + org_x_size):
                    sx = x - left

                    # UV wrapping modes - U component (for X texture coordinate)
                    if placement.placed.wrap_u == TextureGlobals.WM_clamp:
                        sx = max(min(sx, tex_x_size - 1), 0)
                    elif placement.placed.wrap_u == TextureGlobals.WM_mirror:
                        sx = (tex_x_size * 2) - 1 - (
                            (-sx - 1) %
                            (tex_x_size * 2)) if sx < 0 else sx % (tex_x_size *
                                                                   2)
                        sx = sx if sx < tex_x_size else 2 * tex_x_size - sx - 1
                    elif placement.placed.wrap_u == TextureGlobals.WM_mirror_once:
                        sx = sx if sx >= 0 else ~sx

                        # Repeat texture
                        sx = tex_x_size - 1 - (
                            (-sx - 1) %
                            tex_x_size) if sx < 0 else sx % tex_x_size
                    elif placement.placed.wrap_u == TextureGlobals.WM_border_color:
                        if sx < 0 or sx >= tex_x_size:
                            continue
                    else:
                        # Repeat texture
                        sx = tex_x_size - 1 - (
                            (-sx - 1) %
                            tex_x_size) if sx < 0 else sx % tex_x_size

                    new_image.set_xel(x, y, texture_img.get_xel(sx, sy))
                    new_image.set_alpha(x, y, texture_img.get_alpha(sx, sy))

                    if alpha_image:
                        alpha_image.set_gray(x, y,
                                             texture_img.get_alpha(sx, sy))

        return new_image, alpha_image, has_alpha, rgb_only