]> git.tdb.fi Git - libs/gltk.git/blob - source/graphic.cpp
0c874c8d1c0dd785e4bfe024822a35139c1fa801
[libs/gltk.git] / source / graphic.cpp
1 /* $Id$
2
3 This file is part of libmspgltk
4 Copyright © 2007  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/gl/immediate.h>
9 #include "graphic.h"
10 #include "resources.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GLtk {
16
17 Graphic::Graphic():
18         texture(0),
19         repeat(false)
20 { }
21
22 void Graphic::render(unsigned wd, unsigned ht) const
23 {
24         GL::VertexArray varr((GL::TEXCOORD2, GL::VERTEX2));
25         RefPtr<GL::VertexArrayBuilder> vab=varr.modify();
26
27         vector<float> x, y;
28         create_coords(0.0f-shadow.left, wd+shadow.right, border.left, border.right, slice.w-border.left-border.right, x);
29         create_coords(0.0f-shadow.bottom, ht+shadow.top, border.bottom, border.top, slice.h-border.bottom-border.top, y);
30
31         vector<float> u, v;
32         create_texcoords(slice.x, slice.x+slice.w, border.left, border.right, texture->get_width(), u);
33         create_texcoords(slice.y, slice.y+slice.h, border.bottom, border.top, texture->get_height(), v);
34
35         unsigned xmin=border.left ? 0 : 1;
36         unsigned xmax=x.size()-(border.right ? 2 : 3);
37         unsigned ymin=border.bottom ? 0 : 1;
38         unsigned ymax=y.size()-(border.top ? 2 : 3);
39
40         texture->bind();
41         GL::Immediate imm((GL::TEXCOORD2,GL::VERTEX2));
42         imm.begin(GL::QUADS);
43         for(unsigned i=ymin; i<=ymax; ++i)
44         {
45                 unsigned i2=(i==0 ? 0 : i==y.size()-2 ? 2 : 1);
46                 for(unsigned j=xmin; j<=xmax; ++j)
47                 {
48                         unsigned j2=(j==0 ? 0 : j==x.size()-2 ? 2 : 1);
49                         imm.texcoord(u[j2], v[i2]);
50                         imm.vertex(x[j], y[i]);
51                         imm.texcoord(u[j2+1], v[i2]);
52                         imm.vertex(x[j+1], y[i]);
53                         imm.texcoord(u[j2+1], v[i2+1]);
54                         imm.vertex(x[j+1], y[i+1]);
55                         imm.texcoord(u[j2], v[i2+1]);
56                         imm.vertex(x[j], y[i+1]);
57                 }
58         }
59         imm.end();
60 }
61
62 void Graphic::create_coords(float low, float high, float brd1, float brd2, float block, vector<float> &coords) const
63 {
64         coords.push_back(low);
65         coords.push_back(low+brd1);
66         if(repeat)
67         {
68                 float space=high-low-brd1-brd2;
69                 unsigned div=max(static_cast<unsigned>(space/block), 1U);
70                 float delta=space/div;
71                 for(unsigned i=1; i<div; ++i)
72                         coords.push_back(low+brd1+delta*i);
73         }
74         coords.push_back(high-brd2);
75         coords.push_back(high);
76 }
77
78 void Graphic::create_texcoords(float low, float high, float brd1, float brd2, float scale, vector<float> &coords) const
79 {
80         coords.push_back(low/scale);
81         coords.push_back((low+brd1)/scale);
82         coords.push_back((high-brd2)/scale);
83         coords.push_back(high/scale);
84 }
85
86
87 Graphic::Loader::Loader(Graphic &g, Resources &r):
88         graph(g),
89         res(r)
90 {
91         add("texture", &Loader::texture);
92         add("slice",   &Loader::slice);
93         add("border",  &Loader::border);
94         add("repeat",  &Graphic::repeat);
95         add("shadow",  &Loader::shadow);
96 }
97
98 void Graphic::Loader::texture(const string &n)
99 {
100         graph.texture=res.get<GL::Texture2D>(n);
101         graph.slice=Geometry(0, 0, graph.texture->get_width(), graph.texture->get_height());
102 }
103
104 void Graphic::Loader::slice(unsigned x, unsigned y, unsigned w, unsigned h)
105 {
106         graph.slice=Geometry(x, y, w, h);
107 }
108
109 void Graphic::Loader::border()
110 {
111         load_sub(graph.border);
112 }
113
114 void Graphic::Loader::shadow()
115 {
116         load_sub(graph.shadow);
117 }
118
119 } // namespace GLtk
120 } // namespace Msp