]> git.tdb.fi Git - libs/gltk.git/blobdiff - source/graphic.cpp
Reorder class members
[libs/gltk.git] / source / graphic.cpp
index d05123ab890f0f342f858840f97f82cc4e68a6c0..0c874c8d1c0dd785e4bfe024822a35139c1fa801 100644 (file)
+/* $Id$
+
+This file is part of libmspgltk
+Copyright © 2007  Mikko Rasa, Mikkosoft Productions
+Distributed under the LGPL
+*/
+
+#include <msp/gl/immediate.h>
 #include "graphic.h"
 #include "resources.h"
 
 using namespace std;
 
-#include <iostream>
-
 namespace Msp {
 namespace GLtk {
 
-Graphic::Graphic(const Resources &r, const string &n):
-       res(r),
-       name(n),
-       texture(0)
+Graphic::Graphic():
+       texture(0),
+       repeat(false)
 { }
 
 void Graphic::render(unsigned wd, unsigned ht) 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<float>(slice.x)/twidth;
-       u[1]=static_cast<float>(slice.x+border.left)/twidth;
-       u[2]=static_cast<float>(slice.x+slice.w-border.right)/twidth;
-       u[3]=static_cast<float>(slice.x+slice.w)/twidth;
-
-       const unsigned theight=texture->get_height();
-       v[0]=static_cast<float>(slice.y)/theight;
-       v[1]=static_cast<float>(slice.y+border.bottom)/theight;
-       v[2]=static_cast<float>(slice.y+slice.h-border.top)/theight;
-       v[3]=static_cast<float>(slice.y+slice.h)/theight;
+       GL::VertexArray varr((GL::TEXCOORD2, GL::VERTEX2));
+       RefPtr<GL::VertexArrayBuilder> vab=varr.modify();
+
+       vector<float> 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<float> 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);
 
-       texture->bind();
        unsigned xmin=border.left ? 0 : 1;
-       unsigned xmax=border.right ? 3 : 2;
+       unsigned xmax=x.size()-(border.right ? 2 : 3);
        unsigned ymin=border.bottom ? 0 : 1;
-       unsigned ymax=border.top ? 3 : 2;
+       unsigned ymax=y.size()-(border.top ? 2 : 3);
 
-       for(unsigned i=ymin; i<ymax; ++i)
+       texture->bind();
+       GL::Immediate imm((GL::TEXCOORD2,GL::VERTEX2));
+       imm.begin(GL::QUADS);
+       for(unsigned i=ymin; i<=ymax; ++i)
        {
-               glBegin(GL_QUAD_STRIP);
+               unsigned i2=(i==0 ? 0 : i==y.size()-2 ? 2 : 1);
                for(unsigned j=xmin; j<=xmax; ++j)
                {
-                       glTexCoord2f(u[j], v[i]);
-                       glVertex2f(x[j], y[i]);
-                       glTexCoord2f(u[j], v[i+1]);
-                       glVertex2f(x[j], y[i+1]);
+                       unsigned j2=(j==0 ? 0 : j==x.size()-2 ? 2 : 1);
+                       imm.texcoord(u[j2], v[i2]);
+                       imm.vertex(x[j], y[i]);
+                       imm.texcoord(u[j2+1], v[i2]);
+                       imm.vertex(x[j+1], y[i]);
+                       imm.texcoord(u[j2+1], v[i2+1]);
+                       imm.vertex(x[j+1], y[i+1]);
+                       imm.texcoord(u[j2], v[i2+1]);
+                       imm.vertex(x[j], y[i+1]);
                }
-               glEnd();
        }
+       imm.end();
+}
+
+void Graphic::create_coords(float low, float high, float brd1, float brd2, float block, vector<float> &coords) const
+{
+       coords.push_back(low);
+       coords.push_back(low+brd1);
+       if(repeat)
+       {
+               float space=high-low-brd1-brd2;
+               unsigned div=max(static_cast<unsigned>(space/block), 1U);
+               float delta=space/div;
+               for(unsigned i=1; i<div; ++i)
+                       coords.push_back(low+brd1+delta*i);
+       }
+       coords.push_back(high-brd2);
+       coords.push_back(high);
+}
+
+void Graphic::create_texcoords(float low, float high, float brd1, float brd2, float scale, vector<float> &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):
-       graph(g)
+Graphic::Loader::Loader(Graphic &g, Resources &r):
+       graph(g),
+       res(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=&graph.res.get_texture(n);
+       graph.texture=res.get<GL::Texture2D>(n);
        graph.slice=Geometry(0, 0, graph.texture->get_width(), graph.texture->get_height());
 }