X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphic.cpp;h=75e10888ecde2eebef7202659aaf21320520fba8;hb=b3234ca0277c5e282a2a0a2558b58edb25750653;hp=611cdb4c790c4a4e16ff879260f72972cc37bacc;hpb=be8ea35fe6eabe4c68d2d337634f21c63c964265;p=libs%2Fgltk.git diff --git a/source/graphic.cpp b/source/graphic.cpp index 611cdb4..75e1088 100644 --- a/source/graphic.cpp +++ b/source/graphic.cpp @@ -1,4 +1,3 @@ -#include #include "graphic.h" #include "resources.h" @@ -8,89 +7,105 @@ namespace Msp { namespace GLtk { Graphic::Graphic(): - texture(0) + texture(0), + repeat(false) { } -void Graphic::render(unsigned wd, unsigned ht) const +void Graphic::build(unsigned wd, unsigned ht, GL::PrimitiveBuilder &bld) const { - float x[4]; - float y[4]; - float u[4]; - float v[4]; - - x[0]=0.0f-shadow.left; - x[1]=x[0]+border.left; - x[3]=wd+shadow.right; - x[2]=x[3]-border.right; - - y[0]=0.0f-shadow.bottom; - y[1]=y[0]+border.bottom; - y[3]=ht+shadow.top; - y[2]=y[3]-border.top; - - const unsigned twidth=texture->get_width(); - u[0]=static_cast(slice.x)/twidth; - u[1]=static_cast(slice.x+border.left)/twidth; - u[2]=static_cast(slice.x+slice.w-border.right)/twidth; - u[3]=static_cast(slice.x+slice.w)/twidth; - - const unsigned theight=texture->get_height(); - v[0]=static_cast(slice.y)/theight; - v[1]=static_cast(slice.y+border.bottom)/theight; - v[2]=static_cast(slice.y+slice.h-border.top)/theight; - v[3]=static_cast(slice.y+slice.h)/theight; - - texture->bind(); - unsigned xmin=border.left ? 0 : 1; - unsigned xmax=border.right ? 3 : 2; - unsigned ymin=border.bottom ? 0 : 1; - unsigned ymax=border.top ? 3 : 2; - - GL::Immediate imm((GL::TEXCOORD2,GL::VERTEX2)); - for(unsigned i=ymin; i x, y; + create_coords(0.0f-shadow.left, wd+shadow.right, border.left, border.right, slice.w-border.left-border.right, x); + create_coords(0.0f-shadow.bottom, ht+shadow.top, border.bottom, border.top, slice.h-border.bottom-border.top, y); + + vector u, v; + create_texcoords(slice.x, slice.x+slice.w, border.left, border.right, texture->get_width(), u); + create_texcoords(slice.y, slice.y+slice.h, border.bottom, border.top, texture->get_height(), v); + + unsigned xmin = border.left ? 0 : 1; + unsigned xmax = x.size()-(border.right ? 2 : 3); + unsigned ymin = border.bottom ? 0 : 1; + unsigned ymax = y.size()-(border.top ? 2 : 3); + + bld.color(1.0f, 1.0f, 1.0f); + for(unsigned i=ymin; i<=ymax; ++i) { - imm.begin(GL::QUAD_STRIP); + unsigned i2 = (i==0 ? 0 : i==y.size()-2 ? 2 : 1); for(unsigned j=xmin; j<=xmax; ++j) { - imm.texcoord(u[j], v[i]); - imm.vertex(x[j], y[i]); - imm.texcoord(u[j], v[i+1]); - imm.vertex(x[j], y[i+1]); + unsigned j2 = (j==0 ? 0 : j==x.size()-2 ? 2 : 1); + if(j==xmin || (j>1 && jxmin) + bld.end(); + bld.begin(GL::TRIANGLE_STRIP); + bld.texcoord(u[j2], v[i2+1]); + bld.vertex(x[j], y[i+1]); + bld.texcoord(u[j2], v[i2]); + bld.vertex(x[j], y[i]); + } + bld.texcoord(u[j2+1], v[i2+1]); + bld.vertex(x[j+1], y[i+1]); + bld.texcoord(u[j2+1], v[i2]); + bld.vertex(x[j+1], y[i]); } - imm.end(); + bld.end(); } } +void Graphic::create_coords(float low, float high, float brd1, float brd2, float block, vector &coords) const +{ + coords.push_back(low); + coords.push_back(low+brd1); + if(repeat) + { + float space = high-low-brd1-brd2; + unsigned div = max(static_cast(space/block), 1U); + float delta = space/div; + for(unsigned i=1; i &coords) const +{ + coords.push_back(low/scale); + coords.push_back((low+brd1)/scale); + coords.push_back((high-brd2)/scale); + coords.push_back(high/scale); +} + Graphic::Loader::Loader(Graphic &g, Resources &r): - graph(g), - res(r) + DataFile::CollectionObjectLoader(g, &r) { add("texture", &Loader::texture); add("slice", &Loader::slice); add("border", &Loader::border); + add("repeat", &Graphic::repeat); add("shadow", &Loader::shadow); } void Graphic::Loader::texture(const string &n) { - graph.texture=res.get(n); - graph.slice=Geometry(0, 0, graph.texture->get_width(), graph.texture->get_height()); + obj.texture = &get_collection().get(n); + obj.slice = Geometry(0, 0, obj.texture->get_width(), obj.texture->get_height()); } void Graphic::Loader::slice(unsigned x, unsigned y, unsigned w, unsigned h) { - graph.slice=Geometry(x, y, w, h); + obj.slice = Geometry(x, y, w, h); } void Graphic::Loader::border() { - load_sub(graph.border); + load_sub(obj.border); } void Graphic::Loader::shadow() { - load_sub(graph.shadow); + load_sub(obj.shadow); } } // namespace GLtk