summaryrefslogtreecommitdiff
path: root/Runtime/GUI/UI9Slicing.cpp
blob: d4c48ca4c81db4575e576d3dd4b79911c16486d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "UI9Slicing.h"
#include "Runtime/Math/MathHelper.h"
#include <cstring>

using namespace std;

static vector<UIVertexLayout> s_Vertices;
static vector<UIIndex> s_Indices;

UI9Slicing::UI9Slicing(int mode, Vector2 horizontal, Vector2 vertical, Vector2 texPixelSize, Vector2 size)
{
	m_Slicing = mode;
	m_Horizontal = horizontal.Clamp(0, texPixelSize.x, 0, texPixelSize.x);
	m_Vertical = vertical.Clamp(0, texPixelSize.y, 0, texPixelSize.y);

	if (m_Horizontal[0] + m_Horizontal[1] > texPixelSize.x || m_Vertical[0] + m_Vertical[1] > texPixelSize.y)
	{
		throw UIMeshException("UI9Slicing wrong parameter.");
	}
	m_TexSize = texPixelSize;
	m_Size = size;
}

void UI9Slicing::Draw()
{
    s_Indices.clear();
    s_Vertices.clear();

    Vector2 tileSize = Vector2(m_TexSize.x - m_Horizontal[0] - m_Horizontal[1], m_TexSize.y - m_Vertical[0] - m_Vertical[1]);
    Vector2 fillSize = Vector2(m_Size.x - m_Horizontal[0] - m_Horizontal[1], m_Size.y - m_Vertical[0] - m_Vertical[1]);
    // horizonal和vertical对应的uv,注意uv在左下角,mesh在左上角
    Vector2 tileUVx = Vector2(m_Horizontal[0] / m_TexSize.x, (m_TexSize.x - m_Horizontal[1]) / m_TexSize.x);
    Vector2 tileUVy = Vector2((m_TexSize.y - m_Vertical[0]) / m_TexSize.y, m_Vertical[1] / m_TexSize.y);

    // fill vertices 
    int row = 2 + ((fillSize.y <= 0) ? 0 : (m_Slicing == Slicing_Simple ? 2 : ceilf((float)fillSize.y / tileSize.y) + 1));
    int colum = 2 + ((fillSize.x <= 0) ? 0 : (m_Slicing == Slicing_Simple ? 2 : ceilf((float)fillSize.x / tileSize.x) + 1));

    for (int r = 0; r < row; ++r)
    {
        UIVertexLayout vert;
        vert.color = Color32::white;
        if (r == 0)
        {
            vert.position.y = 0;
            vert.uv.y = 1;
        }
        else if (r == row - 1)
        {
            vert.position.y = m_Size.y;
            vert.uv.y = 0;
        }
        else {
            if (m_Slicing == Slicing_Tiled) {
                vert.position.y = clamp(m_Vertical[0] + (r - 1) * tileSize.y, m_Vertical[0], m_Size.y - m_Vertical[1]);
                vert.uv.y = odd(r - 1) ? tileUVy[1] : tileUVy[0];
            } else {
                vert.position.y = odd(r - 1) ? m_Size.y - m_Vertical[1] : m_Vertical[0];
                vert.uv.y = odd(r - 1) ? tileUVy[1] : tileUVy[0];
            }
        }
        for (int c = 0; c < colum; ++c)
        {
            if (c == 0)
            {
                vert.position.x = 0;
                vert.uv.x = 0;
            }
            else if (c == colum - 1)
            {
                vert.position.x = m_Size.x;
                vert.uv.x = 1;
            }
            else {
                if (m_Slicing == Slicing_Tiled) {
                    vert.position.x = clamp(m_Horizontal[0] + (c - 1) * tileSize.x, m_Horizontal[0], m_Size.x - m_Horizontal[0]);
                    vert.uv.x = odd(c - 1) ? tileUVx[1] : tileUVx[0];
                } else {
                    vert.position.x = odd(c - 1) ? (m_Size.x - m_Horizontal[1]) : m_Horizontal[0];
                    vert.uv.x = odd(c - 1) ? tileUVx[1] : tileUVx[0];
                }
            }
            s_Vertices.push_back(vert);

            if (c < colum - 1 && r < row - 1) {
                int index = c + r * colum;
                s_Indices.push_back(index); s_Indices.push_back(index + colum); s_Indices.push_back(index + colum + 1);
                s_Indices.push_back(index + colum + 1); s_Indices.push_back(index + 1); s_Indices.push_back(index);
            }
        }
    }

	void* vb;
    void* ib;

    int vertCount = s_Vertices.size();
    int indicesCount = s_Indices.size();

	g_SharedVBO.GetChunk(sizeof(UIVertexLayout), sizeof(UIIndex), vertCount, indicesCount, Primitive_Triangle, &vb, &ib);

    memcpy(vb, &s_Vertices[0], vertCount * sizeof(UIVertexLayout));
    memcpy(ib, &s_Indices[0], indicesCount* sizeof(UIIndex));

    s_Indices.resize(0);
    s_Vertices.resize(0);

	g_SharedVBO.ReleaseChunk(vertCount, indicesCount);
	g_SharedVBO.DrawChunk(s_UIVertexLayout);
}