source: trunk/src/gl/texture_atlas.cc @ 27

Last change on this file since 27 was 27, checked in by melon, 12 years ago

Reformating.

Removed unused variables.

File size: 2.5 KB
RevLine 
[11]1// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz
2// http://chaosforge.org/
3//
4// This file is part of NV Libraries.
5// For conditions of distribution and use, see copyright notice in nv.hh
6
7#include "nv/gl/texture_atlas.hh"
8
[13]9#include "nv/logging.hh"
10
[11]11using namespace nv;
12
13texture_atlas::texture_atlas( glm::ivec2 size, size_t depth )
[13]14        : image( size, depth ), m_used( 0 )
[11]15{
16        m_nodes.push_back( glm::ivec3( 1, 1, m_size.x - 2 ) );
17        fill( 0 );
18}
19
[13]20region texture_atlas::get_region( glm::ivec2 size )
[11]21{
[13]22        region r ( glm::ivec2(0,0), size );
[11]23
[27]24        int best_height = INT_MAX;
25        int best_index  = -1;
26        int best_width  = INT_MAX;
[11]27        for( size_t i=0; i < m_nodes.size(); ++i )
28        {
[27]29                int y = fit( i, size );
[11]30                if( y >= 0 )
31                {
[27]32                        glm::ivec3 node = m_nodes[ i ];
[11]33                        if ( ( (y + size.y) < best_height ) ||
[27]34                                ( ((y + size.y) == best_height) && (node.z < best_width)) )
[11]35                        {
36                                best_height = y + size.y;
37                                best_index = i;
38                                best_width = node.z;
[13]39                                r.pos.x = node.x;
40                                r.pos.y = y;
[11]41                        }
[27]42                }
43        }
[11]44   
[27]45        if ( best_index == -1 )
46        {
47                return region( glm::ivec2( -1, -1 ), glm::ivec2( 0, 0 ) );
48        }
[11]49
[27]50        m_nodes.insert( m_nodes.begin() + best_index, glm::ivec3( r.pos.x, r.pos.y + size.y, size.x ) );
[11]51
[27]52        for( size_t i = best_index+1; i < m_nodes.size(); ++i )
53        {
54                glm::ivec3 node = m_nodes[ i ];
55                glm::ivec3 prev = m_nodes[ i-1 ];
[11]56
[27]57                if (node.x < (prev.x + prev.z) )
58                {
59                        int shrink = prev.x + prev.z - node.x;
[11]60                        m_nodes[ i ].x += shrink;
61                        m_nodes[ i ].z -= shrink;
62
[27]63                        if (m_nodes[ i ].z <= 0)
64                        {
[11]65                                m_nodes.erase( m_nodes.begin() + i );
[27]66                                --i;
67                        }
68                        else
69                        {
70                                break;
71                        }
72                }
73                else
74                {
75                        break;
76                }
77        }
78        merge();
79        m_used += size.x * size.y;
80        return r;
[11]81}
82
83int texture_atlas::fit( size_t index, glm::ivec2 size )
84{
85        glm::ivec3 node = m_nodes[ index ];
86
87        if ( (  node.x + size.x ) > ( m_size.x - 1 ) )
88        {
89                return -1;
90        }
91
92        int y     = node.y;
93        int wleft = size.x;
94
95        while( wleft > 0 )
96        {
[27]97                node = m_nodes[ index ];
98                if( node.y > y )
99                {
100                        y = node.y;
101                }
[11]102                if( (y + size.y) > (m_size.y-1) )
[27]103                {
[11]104                        return -1;
[27]105                }
[11]106                wleft -= node.z;
[27]107                ++index;
[11]108        }
109        return y;
110}
111
112void texture_atlas::merge()
113{
114        for( size_t i=0; i < m_nodes.size()-1; ++i )
115    {
116                if( m_nodes[ i ].y == m_nodes[ i+1 ].y )
117                {
118                        m_nodes[ i ].z += m_nodes[ i+1 ].z;
119            m_nodes.erase( m_nodes.begin()+i+1 );
120                        --i;
121                }
122    }
123}
124
125void texture_atlas::clear()
126{
127        m_nodes.clear();
128        m_used = 0;
129        m_nodes.push_back( glm::ivec3( 1, 1, m_size.x - 2 ) );
130        fill( 0 );
131}
Note: See TracBrowser for help on using the repository browser.