/
drawlist.h
229 lines (198 loc) · 7.05 KB
/
drawlist.h
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
224
225
226
227
228
229
/** @file drawlist.h Drawable primitive list.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2006-2015 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details. You should have received a copy of the GNU
* General Public License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA</small>
*/
#ifndef CLIENT_RENDER_DRAWLIST_H
#define CLIENT_RENDER_DRAWLIST_H
#include <array>
#include <QFlags>
#include <de/GLBuffer>
#include <de/Vector>
#include "api_gl.h" // blendmode_e
#include "gl/gltextureunit.h"
struct Store;
/// Semantic geometry group identifiers.
enum GeomGroup
{
UnlitGeom = 0, ///< Normal, unlit geometries.
LitGeom, ///< Normal, lit goemetries.
SkyMaskGeom, ///< Sky mask geometries.
LightGeom, ///< Dynamic light geometries.
ShadowGeom, ///< Map object and/or Fake Radio shadow geometries.
ShineGeom ///< Surface reflection geometries.
};
/// Logical drawing modes.
enum DrawMode
{
DM_SKYMASK,
DM_ALL,
DM_LIGHT_MOD_TEXTURE,
DM_FIRST_LIGHT,
DM_TEXTURE_PLUS_LIGHT,
DM_UNBLENDED_TEXTURE_AND_DETAIL,
DM_BLENDED,
DM_BLENDED_FIRST_LIGHT,
DM_NO_LIGHTS,
DM_WITHOUT_TEXTURE,
DM_LIGHTS,
DM_MOD_TEXTURE,
DM_MOD_TEXTURE_MANY_LIGHTS,
DM_UNBLENDED_MOD_TEXTURE_AND_DETAIL,
DM_BLENDED_MOD_TEXTURE,
DM_ALL_DETAILS,
DM_BLENDED_DETAILS,
DM_SHADOW,
DM_SHINY,
DM_MASKED_SHINY,
DM_ALL_SHINY
};
/// Virtual/logical texture unit indices. These map to real GL texture units.
enum texunitid_t
{
TU_PRIMARY = 0,
TU_PRIMARY_DETAIL,
TU_INTER,
TU_INTER_DETAIL,
NUM_TEXTURE_UNITS
};
struct AttributeSpec
{
enum Semantic
{
TexCoord0,
TexCoord1,
ModTexCoord,
NUM_SEMANTICS
};
};
typedef std::array<de::dint, MAX_TEX_UNITS> TexUnitMap;
/**
* A list of drawable GL geometry primitives (buffered) and optional GL attribute/state commands.
*
* Each list is expected to contain a batch (set) of one or more geometry primitives which have been
* pre-prepared for uploading to GL from their backing store (buffer). Primitives should be batched
* together in order to minimize the number of GL state changes when drawing geometry.
*
* Presently @ref DrawLists (class) is responsible for managing the lists and assigning list(s) for
* a given primitive (according to the current logic for geometry batching).
*/
class DrawList
{
public:
struct Spec
{
GeomGroup group;
de::GLTextureUnit texunits[NUM_TEXTURE_UNITS];
Spec(GeomGroup group = UnlitGeom) : group(group)
{}
inline de::GLTextureUnit &unit(int index) {
DENG2_ASSERT(index >= 0 && index < NUM_TEXTURE_UNITS);
return texunits[index];
}
inline de::GLTextureUnit const &unit(int index) const {
DENG2_ASSERT(index >= 0 && index < NUM_TEXTURE_UNITS);
return texunits[index];
}
};
typedef QVector<de::duint> Indices;
struct PrimitiveParams
{
de::gl::Primitive type;
// GL state and flags.
enum Flag {
Unlit = 0,
OneLight = 0x1000,
ManyLights = 0x2000
};
Q_DECLARE_FLAGS(Flags, Flag)
de::duint32 flags_blendMode;
de::Vector2f texScale;
de::Vector2f texOffset;
de::Vector2f detailTexScale;
de::Vector2f detailTexOffset;
DGLuint modTexture; ///< GL-name of the modulation texture; otherwise @c 0.
de::Vector3f modColor; ///< Modulation color.
PrimitiveParams(de::gl::Primitive type,
de::Vector2f texScale = de::Vector2f(1, 1),
de::Vector2f texOffset = de::Vector2f(0, 0),
de::Vector2f detailTexScale = de::Vector2f(1, 1),
de::Vector2f detailTexOffset = de::Vector2f(0, 0),
Flags flags = Unlit,
blendmode_t blendMode = BM_NORMAL,
DGLuint modTexture = 0,
de::Vector3f modColor = de::Vector3f());
};
public:
/**
* Construct a new draw list.
*
* @param spec List specification. A copy is made.
*/
DrawList(Spec const &spec);
/**
* Write indices for a (buffered) geometry primitive to the list.
*
* @param buffer Geometry buffer containing the primitive to write.
* It is the caller's responsibility to ensure this data
* remains accessible and valid while this DrawList is used
* (i.e., until a @ref clear(), rewind() or the
* list itself is destroyed).
* @param primParams GL primitive parameters.
* @param indices Indices for the vertex elements in @a buffer. A copy is made.
*/
DrawList &write(Store const &buffer,
de::duint const *indices, int indexCount,
PrimitiveParams const &primParms);
DrawList &write(Store const &buffer,
Indices const &indices,
de::gl::Primitive primitiveType); // using default parameters
DrawList &write(Store const &buffer,
Indices const &indices,
PrimitiveParams const &primParms);
void draw(DrawMode mode, TexUnitMap const &texUnitMap) const;
/**
* Returns @c true iff there are no commands/geometries in the list.
*/
bool isEmpty() const;
/**
* Clear the list of all buffered GL commands, returning it to the default, empty state.
*/
void clear();
/**
* Return the read/write cursor to the beginning of the list, retaining all allocated
* storage for buffered GL commands so that it can be reused.
*
* To be called at the beginning of a new render frame before any geometry is written
* to the list.
*/
void rewind();
/**
* Provides mutable access to the list's specification. Note that any changes to this
* configuration will affect @em all geometry in the list.
*/
Spec &spec();
/**
* Provides immutable access to the list's specification.
*/
Spec const &spec() const;
private:
DENG2_PRIVATE(d)
};
typedef DrawList::Spec DrawListSpec;
Q_DECLARE_OPERATORS_FOR_FLAGS(DrawList::PrimitiveParams::Flags)
#endif // CLIENT_RENDER_DRAWLIST_H