+ class scenery : public drawable, public cullable
+ {
+ public:
+ scenery(const matrix4& transform, const std::string& textureName) :
+ transformation(transform),
+ image(textureName) {}
+
+ protected:
+ matrix4 transformation;
+ tilemap image;
+ bool blending;
+ long detail;
+ bool fog;
+ };
+
+ class tiles : public scenery
+ {
+ public:
+ tiles(const matrix4& transform, const std::string& textureName,
+ serializable_ptr root) :
+ scenery(transform, textureName),
+ width(1),
+ height(1)
+ {
+ std::map<std::string,serializable_ptr> rootObj;
+
+ if (root->get(rootObj))
+ {
+ std::map<std::string,serializable_ptr>::iterator it;
+
+ if ((it = rootObj.find("width")) != rootObj.end())
+ {
+ (*it).second->get(width);
+ }
+ if ((it = rootObj.find("tiles")) != rootObj.end())
+ {
+ std::vector<serializable_ptr> theTiles;
+
+ if ((*it).second->get(theTiles))
+ {
+ std::vector<serializable_ptr>::iterator jt;
+
+ height = theTiles.size() / width;
+ int w, h;
+
+ indices.resize(height);
+
+ for (h = height - 1, jt = theTiles.begin();
+ jt != theTiles.end(); h--)
+ {
+ std::vector<unsigned> row;
+
+ for (w = 0; w < width && jt != theTiles.end();
+ w++, jt++)
+ {
+ long index;
+
+ if ((*jt)->get(index))
+ {
+ row.push_back(unsigned(index));
+ }
+ }
+
+ indices[h] = row;
+ }
+ }
+ }
+ }
+ }
+
+ void draw(scalar alpha)
+ {
+ glPushMatrix();
+ //std::cout << "transforming..." << std::endl;
+ //std::cout << transformation << std::endl;
+ glMultMatrixf(transformation.data());
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ image.bind();
+
+ long x, y;
+ scalar xf, yf;
+
+ for (y = 0, yf = 0.0; y < height; y++, yf += 1.0)
+ {
+ for (x = 0, xf = 0.0; x < width; x++, xf += 1.0)
+ {
+ scalar texCoords[8];
+
+ unsigned index = indices[y][x];
+
+ if (image.getTileCoords(index, texCoords))
+ {
+ glBegin(GL_TRIANGLE_FAN);
+ glTexCoord2f(texCoords[0], texCoords[1]);
+ glVertex3f(xf, yf, 0.0f);
+ glTexCoord2f(texCoords[2], texCoords[3]);
+ glVertex3f(xf+1.0, yf, 0.0f);
+ glTexCoord2f(texCoords[4], texCoords[5]);
+ glVertex3f(xf+1.0, yf+1.0, 0.0f);
+ glTexCoord2f(texCoords[6], texCoords[7]);
+ glVertex3f(xf, yf+1.0, 0.0f);
+ glEnd();
+ }
+ }
+ }
+
+ glPopMatrix();
+ }
+
+ bool isVisible(const camera& cam)
+ {
+ return true;
+ }
+
+ private:
+ long width, height;
+ std::vector<std::vector<unsigned> > indices;
+ };
+
+ class billboard : public scenery
+ {
+ public:
+ billboard(const matrix4& transform, const std::string& textureName,
+ serializable_ptr root) :
+ scenery(transform, textureName),
+ index(0)
+ {
+ std::map<std::string,serializable_ptr> rootObj;
+
+ if (root->get(rootObj))
+ {
+ std::map<std::string,serializable_ptr>::iterator it;
+
+ if ((it = rootObj.find("tile")) != rootObj.end())
+ {
+ long value;
+ if ((*it).second->get(value))
+ {
+ index = unsigned(value);
+ }
+ }
+ }
+
+ image.getTileCoords(index, texCoords);
+ }
+
+ void draw(scalar alpha)
+ {
+ glPushMatrix();
+ glMultMatrixf(transformation.data());
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ image.bind();
+
+ glBegin(GL_TRIANGLE_FAN);
+ glTexCoord2f(texCoords[0], texCoords[1]);
+ glVertex2f(0.0f, 0.0f);
+ glTexCoord2f(texCoords[2], texCoords[3]);
+ glVertex2f(1.0f, 0.0f);
+ glTexCoord2f(texCoords[4], texCoords[5]);
+ glVertex2f(1.0f, 1.0f);
+ glTexCoord2f(texCoords[6], texCoords[7]);
+ glVertex2f(0.0f, 1.0f);
+ glEnd();
+
+ glPopMatrix();
+ }
+
+ bool isVisible(const camera& cam)
+ {
+ return false;
+ }
+
+ private:
+ unsigned index;
+ scalar texCoords[8];
+ };
+
+