]> git.tdb.fi Git - libs/gltk.git/blob - source/graphic.cpp
Use size_t to represent counts and indices
[libs/gltk.git] / source / graphic.cpp
1 #include "graphic.h"
2 #include "resources.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace GLtk {
8
9 void Graphic::build(unsigned wd, unsigned ht, GL::PrimitiveBuilder &bld) const
10 {
11         vector<float> x, y;
12         create_coords(0.0f-shadow.left, wd+shadow.right, border.left, border.right, slice.w-border.left-border.right, x);
13         create_coords(0.0f-shadow.bottom, ht+shadow.top, border.bottom, border.top, slice.h-border.bottom-border.top, y);
14
15         vector<float> u, v;
16         create_texcoords(slice.x, slice.x+slice.w, border.left, border.right, texture->get_width(), u);
17         create_texcoords(slice.y, slice.y+slice.h, border.bottom, border.top, texture->get_height(), v);
18
19         size_t xmin = border.left ? 0 : 1;
20         size_t xmax = x.size()-(border.right ? 2 : 3);
21         size_t ymin = border.bottom ? 0 : 1;
22         size_t ymax = y.size()-(border.top ? 2 : 3);
23
24         bld.color(1.0f, 1.0f, 1.0f);
25         for(size_t i=ymin; i<=ymax; ++i)
26         {
27                 size_t i2 = (i==0 ? 0 : i==y.size()-2 ? 2 : 1);
28                 for(size_t j=xmin; j<=xmax; ++j)
29                 {
30                         size_t j2 = (j==0 ? 0 : j==x.size()-2 ? 2 : 1);
31                         if(j==xmin || (j>1 && j<x.size()-2))
32                         {
33                                 if(j>xmin)
34                                         bld.end();
35                                 bld.begin(GL::TRIANGLE_STRIP);
36                                 bld.texcoord(u[j2], v[i2+1]);
37                                 bld.vertex(x[j], y[i+1]);
38                                 bld.texcoord(u[j2], v[i2]);
39                                 bld.vertex(x[j], y[i]);
40                         }
41                         bld.texcoord(u[j2+1], v[i2+1]);
42                         bld.vertex(x[j+1], y[i+1]);
43                         bld.texcoord(u[j2+1], v[i2]);
44                         bld.vertex(x[j+1], y[i]);
45                 }
46                 bld.end();
47         }
48 }
49
50 void Graphic::create_coords(float low, float high, float brd1, float brd2, float block, vector<float> &coords) const
51 {
52         coords.push_back(low);
53         coords.push_back(low+brd1);
54         if(repeat)
55         {
56                 float space = high-low-brd1-brd2;
57                 unsigned div = max(static_cast<unsigned>(space/block), 1U);
58                 float delta = space/div;
59                 for(unsigned i=1; i<div; ++i)
60                         coords.push_back(low+brd1+delta*i);
61         }
62         coords.push_back(high-brd2);
63         coords.push_back(high);
64 }
65
66 void Graphic::create_texcoords(float low, float high, float brd1, float brd2, float scale, vector<float> &coords) const
67 {
68         coords.push_back(low/scale);
69         coords.push_back((low+brd1)/scale);
70         coords.push_back((high-brd2)/scale);
71         coords.push_back(high/scale);
72 }
73
74
75 Graphic::Loader::Loader(Graphic &g, Resources &r):
76         DataFile::CollectionObjectLoader<Graphic, Resources>(g, &r)
77 {
78         add("texture", &Loader::texture);
79         add("slice",   &Loader::slice);
80         add("border",  &Loader::border);
81         add("repeat",  &Graphic::repeat);
82         add("shadow",  &Loader::shadow);
83 }
84
85 void Graphic::Loader::texture(const string &n)
86 {
87         obj.texture = &get_collection().get<GL::Texture2D>(n);
88         obj.slice = Geometry(0, 0, obj.texture->get_width(), obj.texture->get_height());
89 }
90
91 void Graphic::Loader::slice(unsigned x, unsigned y, unsigned w, unsigned h)
92 {
93         obj.slice = Geometry(x, y, w, h);
94 }
95
96 void Graphic::Loader::border()
97 {
98         load_sub(obj.border);
99 }
100
101 void Graphic::Loader::shadow()
102 {
103         load_sub(obj.shadow);
104 }
105
106 } // namespace GLtk
107 } // namespace Msp