1 /** @file drawlist.h Drawable primitive list. 2 * 3 * @authors Copyright © 2003-2017 Jaakko Keränen <jaakko.keranen@iki.fi> 4 * @authors Copyright © 2006-2015 Daniel Swanson <danij@dengine.net> 5 * 6 * @par License 7 * GPL: http://www.gnu.org/licenses/gpl.html 8 * 9 * <small>This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by the 11 * Free Software Foundation; either version 2 of the License, or (at your 12 * option) any later version. This program is distributed in the hope that it 13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 * Public License for more details. You should have received a copy of the GNU 16 * General Public License along with this program; if not, write to the Free 17 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 * 02110-1301 USA</small> 19 */ 20 21 #ifndef CLIENT_RENDER_DRAWLIST_H 22 #define CLIENT_RENDER_DRAWLIST_H 23 24 #include <array> 25 #include <QFlags> 26 #include <de/GLBuffer> 27 #include <de/Vector> 28 #include "api_gl.h" // blendmode_e 29 #include "gl/gltextureunit.h" 30 31 struct Store; 32 33 /// Semantic geometry group identifiers. 34 enum GeomGroup 35 { 36 UnlitGeom = 0, ///< Normal, unlit geometries. 37 LitGeom, ///< Normal, lit goemetries. 38 SkyMaskGeom, ///< Sky mask geometries. 39 LightGeom, ///< Dynamic light geometries. 40 ShadowGeom, ///< Map object and/or Fake Radio shadow geometries. 41 ShineGeom ///< Surface reflection geometries. 42 }; 43 44 /// Logical drawing modes. 45 enum DrawMode 46 { 47 DM_SKYMASK, 48 DM_ALL, 49 DM_LIGHT_MOD_TEXTURE, 50 DM_FIRST_LIGHT, 51 DM_TEXTURE_PLUS_LIGHT, 52 DM_UNBLENDED_TEXTURE_AND_DETAIL, 53 DM_BLENDED, 54 DM_BLENDED_FIRST_LIGHT, 55 DM_NO_LIGHTS, 56 DM_WITHOUT_TEXTURE, 57 DM_LIGHTS, 58 DM_MOD_TEXTURE, 59 DM_MOD_TEXTURE_MANY_LIGHTS, 60 DM_UNBLENDED_MOD_TEXTURE_AND_DETAIL, 61 DM_BLENDED_MOD_TEXTURE, 62 DM_ALL_DETAILS, 63 DM_BLENDED_DETAILS, 64 DM_SHADOW, 65 DM_SHINY, 66 DM_MASKED_SHINY, 67 DM_ALL_SHINY 68 }; 69 70 /// Virtual/logical texture unit indices. These map to real GL texture units. 71 enum texunitid_t 72 { 73 TU_PRIMARY = 0, 74 TU_PRIMARY_DETAIL, 75 TU_INTER, 76 TU_INTER_DETAIL, 77 NUM_TEXTURE_UNITS 78 }; 79 80 struct AttributeSpec 81 { 82 enum Semantic 83 { 84 TexCoord0, 85 TexCoord1, 86 ModTexCoord, 87 88 NUM_SEMANTICS 89 }; 90 }; 91 typedef std::array<de::dint, MAX_TEX_UNITS> TexUnitMap; 92 93 /** 94 * A list of drawable GL geometry primitives (buffered) and optional GL attribute/state commands. 95 * 96 * Each list is expected to contain a batch (set) of one or more geometry primitives which have been 97 * pre-prepared for uploading to GL from their backing store (buffer). Primitives should be batched 98 * together in order to minimize the number of GL state changes when drawing geometry. 99 * 100 * Presently @ref DrawLists (class) is responsible for managing the lists and assigning list(s) for 101 * a given primitive (according to the current logic for geometry batching). 102 */ 103 class DrawList 104 { 105 public: 106 struct Spec 107 { 108 GeomGroup group; 109 de::GLTextureUnit texunits[NUM_TEXTURE_UNITS]; 110 groupSpec111 Spec(GeomGroup group = UnlitGeom) : group(group) 112 {} 113 unitSpec114 inline de::GLTextureUnit &unit(int index) { 115 DENG2_ASSERT(index >= 0 && index < NUM_TEXTURE_UNITS); 116 return texunits[index]; 117 } 118 unitSpec119 inline de::GLTextureUnit const &unit(int index) const { 120 DENG2_ASSERT(index >= 0 && index < NUM_TEXTURE_UNITS); 121 return texunits[index]; 122 } 123 }; 124 125 typedef QVector<de::duint> Indices; 126 127 struct PrimitiveParams 128 { 129 de::gl::Primitive type; 130 131 // GL state and flags. 132 enum Flag { 133 Unlit = 0, 134 OneLight = 0x1000, 135 ManyLights = 0x2000 136 }; 137 Q_DECLARE_FLAGS(Flags, Flag) 138 139 de::duint32 flags_blendMode; 140 de::Vector2f texScale; 141 de::Vector2f texOffset; 142 de::Vector2f detailTexScale; 143 de::Vector2f detailTexOffset; 144 DGLuint modTexture; ///< GL-name of the modulation texture; otherwise @c 0. 145 de::Vector3f modColor; ///< Modulation color. 146 147 PrimitiveParams(de::gl::Primitive type, 148 de::Vector2f texScale = de::Vector2f(1, 1), 149 de::Vector2f texOffset = de::Vector2f(0, 0), 150 de::Vector2f detailTexScale = de::Vector2f(1, 1), 151 de::Vector2f detailTexOffset = de::Vector2f(0, 0), 152 Flags flags = Unlit, 153 blendmode_t blendMode = BM_NORMAL, 154 DGLuint modTexture = 0, 155 de::Vector3f modColor = de::Vector3f()); 156 }; 157 158 public: 159 /** 160 * Construct a new draw list. 161 * 162 * @param spec List specification. A copy is made. 163 */ 164 DrawList(Spec const &spec); 165 166 /** 167 * Write indices for a (buffered) geometry primitive to the list. 168 * 169 * @param buffer Geometry buffer containing the primitive to write. 170 * It is the caller's responsibility to ensure this data 171 * remains accessible and valid while this DrawList is used 172 * (i.e., until a @ref clear(), rewind() or the 173 * list itself is destroyed). 174 * @param primParams GL primitive parameters. 175 * @param indices Indices for the vertex elements in @a buffer. A copy is made. 176 */ 177 DrawList &write(Store const &buffer, 178 de::duint const *indices, int indexCount, 179 PrimitiveParams const &primParms); 180 181 DrawList &write(Store const &buffer, 182 de::duint const *indices, int indexCount, 183 de::gl::Primitive primitiveType); // using default parameters 184 185 DrawList &write(Store const &buffer, 186 Indices const &indices, 187 PrimitiveParams const &primParms); 188 189 DrawList &write(Store const &buffer, 190 Indices const &indices, 191 de::gl::Primitive primitiveType); // using default parameters 192 193 void draw(DrawMode mode, TexUnitMap const &texUnitMap) const; 194 195 /** 196 * Returns @c true iff there are no commands/geometries in the list. 197 */ 198 bool isEmpty() const; 199 200 /** 201 * Clear the list of all buffered GL commands, returning it to the default, empty state. 202 */ 203 void clear(); 204 205 /** 206 * Return the read/write cursor to the beginning of the list, retaining all allocated 207 * storage for buffered GL commands so that it can be reused. 208 * 209 * To be called at the beginning of a new render frame before any geometry is written 210 * to the list. 211 */ 212 void rewind(); 213 214 /** 215 * Provides mutable access to the list's specification. Note that any changes to this 216 * configuration will affect @em all geometry in the list. 217 */ 218 Spec &spec(); 219 220 /** 221 * Provides immutable access to the list's specification. 222 */ 223 Spec const &spec() const; 224 225 public: 226 static void reserveSpace(Indices &idx, uint count); 227 228 private: 229 DENG2_PRIVATE(d) 230 }; 231 232 typedef DrawList::Spec DrawListSpec; 233 234 Q_DECLARE_OPERATORS_FOR_FLAGS(DrawList::PrimitiveParams::Flags) 235 236 #endif // CLIENT_RENDER_DRAWLIST_H 237