1 /** 2 * Copyright (c) 2006-2016 LOVE Development Team 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * 8 * Permission is granted to anyone to use this software for any purpose, 9 * including commercial applications, and to alter it and redistribute it 10 * freely, subject to the following restrictions: 11 * 12 * 1. The origin of this software must not be misrepresented; you must not 13 * claim that you wrote the original software. If you use this software 14 * in a product, an acknowledgment in the product documentation would be 15 * appreciated but is not required. 16 * 2. Altered source versions must be plainly marked as such, and must not be 17 * misrepresented as being the original software. 18 * 3. This notice may not be removed or altered from any source distribution. 19 **/ 20 21 #ifndef LOVE_GRAPHICS_OPENGL_MESH_H 22 #define LOVE_GRAPHICS_OPENGL_MESH_H 23 24 // LOVE 25 #include "common/config.h" 26 #include "common/int.h" 27 #include "common/math.h" 28 #include "common/StringMap.h" 29 #include "graphics/Drawable.h" 30 #include "graphics/Texture.h" 31 #include "GLBuffer.h" 32 33 // C++ 34 #include <vector> 35 #include <unordered_map> 36 37 namespace love 38 { 39 namespace graphics 40 { 41 namespace opengl 42 { 43 44 /** 45 * Holds and draws arbitrary vertex geometry. 46 * Each vertex in the Mesh has a collection of vertex attributes specified on 47 * creation. 48 **/ 49 class Mesh : public Drawable 50 { 51 public: 52 53 // The expected usage pattern of the Mesh's vertex data. 54 enum Usage 55 { 56 USAGE_STREAM, 57 USAGE_DYNAMIC, 58 USAGE_STATIC, 59 USAGE_MAX_ENUM 60 }; 61 62 // How the Mesh's vertices are used when drawing. 63 // http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png 64 enum DrawMode 65 { 66 DRAWMODE_FAN, 67 DRAWMODE_STRIP, 68 DRAWMODE_TRIANGLES, 69 DRAWMODE_POINTS, 70 DRAWMODE_MAX_ENUM 71 }; 72 73 // The type of data a vertex attribute can store. 74 enum DataType 75 { 76 DATA_BYTE, 77 DATA_FLOAT, 78 DATA_MAX_ENUM 79 }; 80 81 struct AttribFormat 82 { 83 std::string name; 84 DataType type; 85 int components; // max 4 86 }; 87 88 Mesh(const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, Usage usage); 89 Mesh(const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, Usage usage); 90 91 Mesh(const std::vector<Vertex> &vertices, DrawMode drawmode, Usage usage); 92 Mesh(int vertexcount, DrawMode drawmode, Usage usage); 93 94 virtual ~Mesh(); 95 96 /** 97 * Sets the values of all attributes at a specific vertex index in the Mesh. 98 * The size of the data must be less than or equal to the total size of all 99 * vertex attributes. 100 **/ 101 void setVertex(size_t vertindex, const void *data, size_t datasize); 102 size_t getVertex(size_t vertindex, void *data, size_t datasize); 103 void *getVertexScratchBuffer(); 104 105 /** 106 * Sets the values for a single attribute at a specific vertex index in the 107 * Mesh. The size of the data must be less than or equal to the size of the 108 * attribute. 109 **/ 110 void setVertexAttribute(size_t vertindex, int attribindex, const void *data, size_t datasize); 111 size_t getVertexAttribute(size_t vertindex, int attribindex, void *data, size_t datasize); 112 113 /** 114 * Gets the total number of vertices that can be used when drawing the Mesh. 115 **/ 116 size_t getVertexCount() const; 117 118 /** 119 * Gets the size in bytes of the start of one vertex to the start of the 120 * next, in the buffer. 121 **/ 122 size_t getVertexStride() const; 123 124 /** 125 * Gets the format of each vertex attribute stored in the Mesh. 126 **/ 127 const std::vector<AttribFormat> &getVertexFormat() const; 128 DataType getAttributeInfo(int attribindex, int &components) const; 129 int getAttributeIndex(const std::string &name) const; 130 131 /** 132 * Sets whether a specific vertex attribute is used when drawing the Mesh. 133 **/ 134 void setAttributeEnabled(const std::string &name, bool enable); 135 bool isAttributeEnabled(const std::string &name) const; 136 137 /** 138 * Attaches a vertex attribute from another Mesh to this one. The attribute 139 * will be used when drawing this Mesh. 140 **/ 141 void attachAttribute(const std::string &name, Mesh *mesh); 142 143 void *mapVertexData(); 144 void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1); 145 146 /** 147 * Flushes all modified data to the GPU. 148 **/ 149 void flush(); 150 151 /** 152 * Sets the vertex map to use when drawing the Mesh. The vertex map 153 * determines the order in which vertices are used by the draw mode. 154 * A 0-element vector is equivalent to the default vertex map: 155 * {0, 1, 2, 3, 4, ...} 156 **/ 157 void setVertexMap(const std::vector<uint32> &map); 158 void setVertexMap(); 159 160 /** 161 * Fills the uint32 vector passed into the method with the previously set 162 * vertex map (index buffer) values. 163 **/ 164 bool getVertexMap(std::vector<uint32> &map) const; 165 166 /** 167 * Gets the total number of elements in the vertex map array. 168 **/ 169 size_t getVertexMapCount() const; 170 171 /** 172 * Sets the texture used when drawing the Mesh. 173 **/ 174 void setTexture(Texture *texture); 175 176 /** 177 * Disables any texture from being used when drawing the Mesh. 178 **/ 179 void setTexture(); 180 181 /** 182 * Gets the texture used when drawing the Mesh. May return null if no 183 * texture is set. 184 **/ 185 Texture *getTexture() const; 186 187 /** 188 * Sets the draw mode used when drawing the Mesh. 189 **/ 190 void setDrawMode(DrawMode mode); 191 DrawMode getDrawMode() const; 192 193 void setDrawRange(int min, int max); 194 void setDrawRange(); 195 void getDrawRange(int &min, int &max) const; 196 197 int bindAttributeToShaderInput(int attributeindex, const std::string &inputname); 198 199 // Implements Drawable. 200 void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) override; 201 202 static GLenum getGLBufferUsage(Usage usage); 203 204 static bool getConstant(const char *in, Usage &out); 205 static bool getConstant(Usage in, const char *&out); 206 207 static bool getConstant(const char *in, DrawMode &out); 208 static bool getConstant(DrawMode in, const char *&out); 209 210 static bool getConstant(const char *in, DataType &out); 211 static bool getConstant(DataType in, const char *&out); 212 213 private: 214 215 struct AttachedAttribute 216 { 217 Mesh *mesh; 218 int index; 219 bool enabled; 220 }; 221 222 void setupAttachedAttributes(); 223 void calculateAttributeSizes(); 224 size_t getAttributeOffset(size_t attribindex) const; 225 226 static size_t getAttribFormatSize(const AttribFormat &format); 227 228 static GLenum getGLDrawMode(DrawMode mode); 229 static GLenum getGLDataType(DataType type); 230 static GLenum getGLDataTypeFromMax(size_t maxvalue); 231 static size_t getGLDataTypeSize(GLenum datatype); 232 233 std::vector<AttribFormat> vertexFormat; 234 std::vector<size_t> attributeSizes; 235 236 std::unordered_map<std::string, AttachedAttribute> attachedAttributes; 237 238 // Vertex buffer, for the vertex data. 239 GLBuffer *vbo; 240 size_t vertexCount; 241 size_t vertexStride; 242 243 // Block of memory whose size is at least as large as a single vertex. Helps 244 // avoid memory allocations when using Mesh::setVertex etc. 245 char *vertexScratchBuffer; 246 247 // Element (vertex index) buffer, for the vertex map. 248 GLBuffer *ibo; 249 bool useIndexBuffer; 250 size_t elementCount; 251 GLenum elementDataType; 252 253 DrawMode drawMode; 254 255 int rangeMin; 256 int rangeMax; 257 258 StrongRef<Texture> texture; 259 260 static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[]; 261 static StringMap<Usage, USAGE_MAX_ENUM> usages; 262 263 static StringMap<DrawMode, DRAWMODE_MAX_ENUM>::Entry drawModeEntries[]; 264 static StringMap<DrawMode, DRAWMODE_MAX_ENUM> drawModes; 265 266 static StringMap<DataType, DATA_MAX_ENUM>::Entry dataTypeEntries[]; 267 static StringMap<DataType, DATA_MAX_ENUM> dataTypes; 268 269 }; // Mesh 270 271 } // opengl 272 } // graphics 273 } // love 274 275 #endif // LOVE_GRAPHICS_OPENGL_MESH_H 276