Beispiel #1
0
    ///
    public void SetTexture(uint atlas_type, Texture2D texture)
    {
        RoveMaterials rove_materials = RoveSetup.GetAPIComponent <RoveMaterials>();

        if (!rove_materials)
        {
            Debug.LogError("Failed set material texture.");
            return;
        }
        RoveTexture rove_texture = m_textures[atlas_type];

        if (texture == null)
        {
            if (rove_texture.m_status != RoveTexture.STATUS_EMPTY)
            {
                rove_texture.m_status = RoveTexture.STATUS_CHANGE;
            }
        }
        else
        {
            if (rove_texture.m_status != RoveTexture.STATUS_OK)
            {
                rove_texture.m_status = RoveTexture.STATUS_NEW;
            }
            else
            {
                rove_texture.m_status = RoveTexture.STATUS_CHANGE;
            }
        }
        rove_texture.m_texture = texture;
        rove_materials.m_atlases[atlas_type].m_dirty = true;
    }
Beispiel #2
0
    ///
    public bool Pack(RoveTexture rove_texture)
    {
        int width  = rove_texture.m_texture.width;
        int height = rove_texture.m_texture.height;

        rove_texture.m_atlas_rect.width  = width;
        rove_texture.m_atlas_rect.height = height;
        int index = m_available.BinarySearch(rove_texture.m_atlas_rect,
                                             new RectWidthAscending());

        if (index < 0)
        {
            index = ~index;
        }
        if (index == m_available.Count)
        {
            return(false);
        }
        else
        {
            while (index < m_available.Count)
            {
                Rect available = m_available[index];
                if (available.height > height)
                {
                    rove_texture.m_atlas_rect.x = available.x;
                    rove_texture.m_atlas_rect.y = available.y;
                    m_available.RemoveAt(index);
                    if (available.width == width)
                    {
                        InsertAvailable(new Rect(available.x, available.y + height,
                                                 available.width, available.height - height));
                    }
                    else
                    {
                        InsertAvailable(new Rect(available.x, available.y + height,
                                                 available.width, available.height - height));
                        InsertAvailable(new Rect(available.x + width, available.y,
                                                 available.width - width, height));
                    }
                    return(true);
                }
                else if (available.height == height)
                {
                    rove_texture.m_atlas_rect.x = available.x;
                    rove_texture.m_atlas_rect.y = available.y;
                    m_available.RemoveAt(index);
                    if (available.width > width)
                    {
                        InsertAvailable(new Rect(available.x + width, available.y,
                                                 available.width - width, available.height));
                    }
                    return(true);
                }
                ++index;
            }
        }
        return(false);
    }
Beispiel #3
0
    ///
    public bool ProcessAtlas()
    {
        if (!m_dirty)
        {
            return(true);
        }
        RoveMaterials rove_materials = RoveSetup.GetAPIComponent <RoveMaterials>();

        if (!rove_materials)
        {
            Debug.LogError("Rove: Failed to begin to process atlas.");
            return(false);
        }
        List <RoveMaterial> materials = rove_materials.m_materials;
        uint map_flag = 0x0;

        if (m_type == RoveAtlas.TYPE_ALBEDO)
        {
            map_flag = RoveMaterials.MAP_FLAG_ALBEDO;
        }
        else if (m_type == RoveAtlas.TYPE_NORMAL)
        {
            map_flag = RoveMaterials.MAP_FLAG_NORMAL;
        }
        else if (m_type == RoveAtlas.TYPE_METALLIC)
        {
            map_flag = RoveMaterials.MAP_FLAG_METALLIC;
        }
        else if (m_type == RoveAtlas.TYPE_EMISSION)
        {
            map_flag = RoveMaterials.MAP_FLAG_EMISSION;
        }
        List <int> dirty_textures = new List <int>();
        int        area           = 0;

        for (int m = 0; m < materials.Count; ++m)
        {
            RoveMaterial material     = materials[m];
            RoveTexture  rove_texture = material.m_textures[m_type];
            uint         status       = rove_texture.m_status;
            if ((status == RoveTexture.STATUS_EMPTY) ||
                (status == RoveTexture.STATUS_OK))
            {
                continue;
            }
            else if (status == RoveTexture.STATUS_CHANGE)
            {
                Remove(rove_texture);
                if (rove_texture.m_texture == null)
                {
                    rove_texture.m_status = RoveTexture.STATUS_EMPTY;
                    material.m_map_flags &= ~map_flag;
                    material.SetMapFlags(material.m_map_flags);
                    continue;
                }
            }
            material.m_map_flags |= map_flag;
            material.SetMapFlags(material.m_map_flags);
            area += rove_texture.m_texture.width * rove_texture.m_texture.height;
            dirty_textures.Add(m);
        }
        int predicted_size = RoveAtlas.PredictSize(area);

        if (predicted_size > m_width)
        {
            if (predicted_size > 16384)
            {
                Debug.LogError("Rove: Predicted atlas exceeds 16384 x 16384, " +
                               "cannot create atlas.");
                return(false);
            }
            m_width = m_height = predicted_size;
            if (!Repack())
            {
                return(false);
            }
        }
        else
        {
            if (dirty_textures.Count > 1)
            {
                dirty_textures.Sort((a, b) =>
                {
                    RoveTexture rove_texture_a = materials[a].m_textures[m_type];
                    RoveTexture rove_texture_b = materials[b].m_textures[m_type];
                    int a_size = rove_texture_a.m_texture.width *
                                 rove_texture_a.m_texture.height;
                    int b_size = rove_texture_b.m_texture.width *
                                 rove_texture_b.m_texture.height;
                    return(b_size.CompareTo(a_size));
                });
            }
            for (int t = 0; t < dirty_textures.Count; ++t)
            {
                RoveMaterial material     = materials[dirty_textures[t]];
                RoveTexture  rove_texture = material.m_textures[m_type];
                if (!Pack(rove_texture))
                {
                    if (!Repack())
                    {
                        return(false);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    material.SetAtlasRect(m_type, rove_texture.m_atlas_rect);
                    rove_texture.m_status = RoveTexture.STATUS_OK;
                }
            }
        }
        RenderTexture temp_rt = RenderTexture.GetTemporary(m_width, m_height,
                                                           0, RenderTextureFormat.ARGB32);

        RenderTexture.active = temp_rt;
        GL.PushMatrix();
        GL.LoadPixelMatrix(0, m_width, m_height, 0);
        GL.Clear(false, true, new Color(0.0f, 0.0f, 0.0f, 1.0f));
        for (int m = 0; m < materials.Count; ++m)
        {
            Texture2D texture = materials[m].m_textures[m_type].m_texture;
            if (texture == null)
            {
                continue;
            }
            Rect bl_origin = new Rect(materials[m].m_textures[m_type].m_atlas_rect);
            bl_origin.y = (m_height - bl_origin.y) - bl_origin.height;
            m_atlas_material.SetTexture("target", materials[m].m_textures[m_type].m_texture);
            Graphics.DrawTexture(bl_origin, texture, m_atlas_material);
        }
        GL.PopMatrix();
        m_texture = new Texture2D(m_width, m_height, TextureFormat.ARGB32, false);
        m_texture.ReadPixels(new Rect(0, 0, m_width, m_height), 0, 0, false);
        m_texture.Apply();
        RenderTexture.active = null;
        RenderTexture.ReleaseTemporary(temp_rt);
        UploadAtlas();
        m_dirty = false;
        return(true);
    }
Beispiel #4
0
    ///
    public bool Repack()
    {
        RoveMaterials rove_materials = RoveSetup.GetAPIComponent <RoveMaterials>();

        if (!rove_materials)
        {
            Debug.LogError("Rove: Failed to begin to process atlas.");
            return(false);
        }
        List <RoveMaterial> materials      = rove_materials.m_materials;
        List <int>          dirty_textures = new List <int>();
        int area = 0;

        for (int t = 0; t < materials.Count; ++t)
        {
            RoveTexture rove_texture = materials[t].m_textures[m_type];
            uint        status       = rove_texture.m_status;
            if ((rove_texture.m_texture == null) ||
                (status == RoveTexture.STATUS_EMPTY))
            {
                continue;
            }
            dirty_textures.Add(t);
            area += rove_texture.m_texture.width * rove_texture.m_texture.height;
        }
        int predicted_size = RoveAtlas.PredictSize(area);

        if (predicted_size > m_width)
        {
            if (predicted_size > 16384)
            {
                Debug.LogError("Rove: Predicted atlas exceeds 16384 x 16384, " +
                               "cannot create atlas.");
                return(false);
            }
            Reset(predicted_size, predicted_size);
        }
        else
        {
            Reset(predicted_size, predicted_size);
        }
        if (dirty_textures.Count > 1)
        {
            dirty_textures.Sort((a, b) =>
            {
                RoveTexture rove_texture_a = materials[a].m_textures[m_type];
                RoveTexture rove_texture_b = materials[b].m_textures[m_type];
                int a_size = rove_texture_a.m_texture.width *
                             rove_texture_a.m_texture.height;
                int b_size = rove_texture_b.m_texture.width *
                             rove_texture_b.m_texture.height;
                return(b_size.CompareTo(a_size));
            });
        }
        bool packed = false;

        while (!packed && (m_width <= 16384) && (m_height <= 16384))
        {
            for (int t = 0; t < dirty_textures.Count; ++t)
            {
                RoveMaterial material     = materials[dirty_textures[t]];
                RoveTexture  rove_texture = material.m_textures[m_type];
                if (!Pack(rove_texture))
                {
                    Reset(m_width * 2, m_height * 2);
                    break;
                }
                else
                {
                    material.SetAtlasRect(m_type, rove_texture.m_atlas_rect);
                    rove_texture.m_status = RoveTexture.STATUS_OK;
                }
                if (t == (dirty_textures.Count - 1))
                {
                    packed = true;
                }
            }
        }
        if (!packed)
        {
            Debug.LogError("Rove: Failed to repack atlas: " + m_type + ".");
            return(false);
        }
        return(true);
    }
Beispiel #5
0
 ///
 public void Remove(RoveTexture rove_texture)
 {
     InsertAvailable(rove_texture.m_atlas_rect);
 }