/* * File: tilebuf.h * Created by: ennewalker on Sat Jan 5 01:33:53 2008 UTC */ #ifndef TILEBUF_H #define TILEBUF_H #include "tiles.h" // This struct defines all of the state that any particular rendering needs. // If other rendering states are needed, they should be added here so that // they do not introduce unneeded side effects for other parts of the code // that have not thought about turning that new state off. struct GLState { GLState(); // vertex arrays bool array_vertex; bool array_texcoord; bool array_colour; // render state bool blend; bool texture; bool depthtest; bool alphatest; unsigned char alpharef; }; class GLStateManager { public: static void init(); static void set(const GLState& state); }; class FTFont; class formatted_string; class GenericTexture; class TilesTexture; #include #include struct VColour { VColour() {} VColour(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a = 255) : r(_r), g(_g), b(_b), a(_a) {} unsigned char r; unsigned char g; unsigned char b; unsigned char a; static VColour white; static VColour black; static VColour transparent; }; struct PTCVert { float pos_x; float pos_y; float tex_x; float tex_y; VColour col; }; struct P3TCVert { float pos_x; float pos_y; float pos_z; float tex_x; float tex_y; VColour col; }; struct PTVert { float pos_x; float pos_y; float tex_x; float tex_y; }; struct PCVert { float pos_x; float pos_y; VColour col; }; // V: vertex data template class VertBuffer : public std::vector { public: typedef V Vert; VertBuffer(const GenericTexture *tex, int prim); // Vertices are fat, so to avoid an extra copy of all the data members, // pre-construct the vertex and return a reference to it. V& get_next(); void draw() const; GLState &state() { return m_state; } protected: void init_state(); const GenericTexture *m_tex; int m_prim; GLState m_state; }; class FontBuffer : public VertBuffer { public: FontBuffer(FTFont *font); void add(const formatted_string &fs, float x, float y); void add(const std::string &s, const VColour &col, float x, float y); protected: FTFont *m_font; }; class TileBuffer : public VertBuffer { public: TileBuffer(const TilesTexture *tex = NULL); void add_unscaled(int idx, float x, float y, int ymax = TILE_Y); void add(int idx, int x, int y, int ox = 0, int oy = 0, bool centre = true, int ymax = -1); // Note: this could invalidate previous additions if they were // from a different texture. void set_tex(const TilesTexture *tex); }; class ColouredTileBuffer : public VertBuffer { public: ColouredTileBuffer(const TilesTexture *tex = NULL); void add(int idx, int x, int y, int z, int ox, int oy, int ymin, int ymax, int alpha_top, int alpha_bottom); }; // Helper class for tiles submerged in water. class SubmergedTileBuffer { public: // mask_idx is the tile index in tex of the mask texture // It should be opaque white for water and fully transparent above. // // above_max is the maximum height (from the top of the tile) where // there are still pixels above water. // // below_min is the minimum height (from the top of the tile) where // there are still pixels below water. // // All heights are from 0 (top of the tile) to TILE_Y-1 (bottom of the tile) SubmergedTileBuffer(const TilesTexture *tex, int mask_idx, int above_max, int below_min); void add(int idx, int x, int y, int z = 0, bool submerged = false, bool ghost = false, int ox = 0, int oy = 0, int ymax = -1); void draw() const; void clear(); protected: int m_mask_idx; int m_above_max; int m_below_min; int m_max_z; ColouredTileBuffer m_below_water; ColouredTileBuffer m_mask; ColouredTileBuffer m_above_water; }; class ShapeBuffer : public VertBuffer { public: ShapeBuffer(); void add(float sx, float sy, float ex, float ey, const VColour &c); }; class LineBuffer : public VertBuffer { public: LineBuffer(); void add(float sx, float sy, float ex, float ey, const VColour &c); void add_square(float sx, float sy, float ex, float ey, const VColour &c); }; ///////////////////////////////////////////////////////////////////////////// // template implementation template inline VertBuffer::VertBuffer(const GenericTexture *tex, int prim) : m_tex(tex), m_prim(prim) { init_state(); } template inline V& VertBuffer::get_next() { size_t last = std::vector::size(); std::vector::resize(last + 1); return ((*this)[last]); } #endif