summaryrefslogblamecommitdiffstats
path: root/crawl-ref/source/tilebuf.h
blob: ee315a6ecaf2fae4a5647be47a40f208d5a97510 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                                                         




                 

                  



























                                                                            




                       
                 


























                                                                   









                
















                 
                                        

       

                   

                                                    

                                                                           
                  
                      
 

                                        
          

                      

                                
                    














                                                                         
                                               
 
                                                                    

                                                                                               





                                                                  












































                                                                                

















                                                                              
                 


                                                                       
                 


                 

                                   


                                         


      
/*
 *  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 <string>
#include <vector>

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 V>
class VertBuffer : public std::vector<V>
{
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<PTCVert>
{
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<PTVert>
{
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<P3TCVert>
{
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<PCVert>
{
public:
    ShapeBuffer();
    void add(float sx, float sy, float ex, float ey, const VColour &c);
};

class LineBuffer : public VertBuffer<PCVert>
{
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<class V>
inline VertBuffer<V>::VertBuffer(const GenericTexture *tex, int prim) :
    m_tex(tex), m_prim(prim)
{
    init_state();
}

template<class V>
inline V& VertBuffer<V>::get_next()
{
    size_t last = std::vector<V>::size();
    std::vector<V>::resize(last + 1);
    return ((*this)[last]);
}

#endif