summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/tilebuf.h
blob: ee315a6ecaf2fae4a5647be47a40f208d5a97510 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 *  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