#ifndef MESH_H #define MESH_H #include "glew.h" #include #include #include class Buffer; class Material; class Shader; struct Mesh { public: /*************************************************************/ /* MESH AND MATERIAL FLAGS */ /*************************************************************/ // Mesh properties enum { // Geometric properties MESH_INDEXED, MESH_TEXTURABLE, MESH_INSTANCED, // Mesh type MESH_3D, MESH_2D, // 3D Geometric properties MESH_TANGENT_SPACE, MESH_BILLBOARD, MESH_SHADOWED, // simple material (no lighting) MATERIAL_COLOR_TEXTURE, MATERIAL_ALPHA_MASK, // 3D phong material MATERIAL_PHONG, MATERIAL_PHONG_DIFFUSE_TEXTURE, MATERIAL_PHONG_AMBIENT_TEXTURE, MATERIAL_PHONG_SPECULAR_TEXTURE, MATERIAL_PHONG_NORMAL_MAP, // 3D Beckman-like materials MATERIAL_BACKMANN_BUMP_MAP, NB_FLAGS }; // shader "#define" strings associated to the properties static const char* const flagStr[NB_FLAGS]; /*************************************************************/ /* GEOMETRY DATA */ /*************************************************************/ // 3D public data std::vector positions3D; std::vector normals; // 2D public data std::vector positions2D; // public data common to 2D and 3D std::vector texCoords; std::vector instances_offsets; std::vector indices; /*************************************************************/ /* MAIN METHODS */ /*************************************************************/ /** * @brief Mesh builds an empty mesh, to be renderable, a mesh must have vertices and a material. */ Mesh(); ~Mesh(); /** * OpenGL methods : * - initGL allocates the GPU buffers and sends the mesh data to the GPU * - draw binds the material attributes and draws the mesh geometry * - destroyGL releases the allocated GPU memory, destroyGL is called automatically in Mesh's destructor and at the beginning of initGL */ void initGL(); void draw(Shader* shader = NULL, bool drawNormals = true, bool drawTexCoord = true, bool drawTangents = true); void destroyGL(); /** * @brief getFlags returns the flags that defines the specificities of the mesh and his material */ unsigned int getFlags(); /*************************************************************/ /* MESH BUILDING METHODS */ /*************************************************************/ // add vertex void addVertex(float x, float y, float z) {addVertex(glm::vec3(x, y, z));} void addVertex(const glm::vec3 &position) {positions3D.push_back(position);} void addVertex(float x, float y) {addVertex(glm::vec2(x, y));} void addVertex(const glm::vec2 &position) {positions2D.push_back(position);} void addVertex(const glm::vec3 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);} void addVertex(const glm::vec2 &position, const glm::vec2 &texCoord) {addVertex(position); addTexCoord(texCoord);} void addVertex(const glm::vec3 &position, const glm::vec3 &normal) {addVertex(position); addNormal(normal);} void addVertex(const glm::vec3 &position, const glm::vec3 &normal, const glm::vec2 &texCoord) {addVertex(position, normal); addTexCoord(texCoord);} // add indices void addTriangle(int i1, int i2, int i3) {indices.push_back(i1), indices.push_back(i2), indices.push_back(i3);} void addLine(int i1, int i2) {indices.push_back(i1), indices.push_back(i2);} // Material accessers void setMaterial(Material* mat) {material = mat;} Material *getMaterial() {return material;} // other accessers void addNormal(float x, float y, float z) {addNormal(glm::vec3(x, y, z));} void addNormal(const glm::vec3 &normal) {normals.push_back(normal);} void addTexCoord(float u, float v) {addTexCoord(glm::vec2(u, v));} void addTexCoord(const glm::vec2 &texCoord) {texCoords.push_back(texCoord);} /*************************************************************/ /* 2D MESH PROPERTIES */ /*************************************************************/ /** * @brief setDepth allows to set the depth of a 2D mesh, the depth must be between -1 and 1, -1 being the closest to the camera */ void setDepth(float d) {depth = d;} /*************************************************************/ /* 3D MESH PROPERTIES */ /*************************************************************/ /** * @brief setIsDoubleSided allows to enable or disable face culling for this Mesh */ void setIsDoubleSided(bool val) {isDoubleSided = val;} /** * @brief setIsBillboard allows to enable or disable billboarding, * a billboard mesh will always follow the camera orientation */ void setIsBillboard(bool val) {isBillboard = val;} /** * @brief setIsShadowCaster allows to enable or disable, * rendering of this mesh in the shadowmaps */ void setIsShadowCaster(bool val) {isShadowCaster = val;} /*************************************************************/ /* 3D MESH TOOLS */ /*************************************************************/ /** * @brief mergeVertices simplifies an indexed mesh by merging all vertices that * have exactly the same position, texcoord, and normals, the tangents will be averaged. */ void mergeVertices(); /** * @brief computeNormals computes adjacency for a triangle mesh, the mesh type changes to GL_TRIANGLES_ADJACENCY */ void computeNeighbors(); /** * compute normals from an indexed mesh (positions + indices) */ void computeNormals(); /** * compute tangent space from a textured indexed mesh (positions + normals + texcoords + indices) */ void computeTangents(); /** * compute the bounding box of the mesh based on the 3D positions */ void computeBoundingBox(glm::vec3 &min, glm::vec3 &max); /*************************************************************/ /* ADVANCED CUSTOMISATION */ /*************************************************************/ /** * Specifies what kind of primitives to render. Symbolic constants GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_LINE_STRIP_ADJACENCY, * GL_LINES_ADJACENCY, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP_ADJACENCY, GL_TRIANGLES_ADJACENCY and GL_PATCHES are accepted. * * default is GL_TRIANGLES */ void setPrimitiveType(GLenum type) {primitive_type = type;} protected: typedef struct { glm::vec3 tangent; glm::vec3 binormal; } Tangents; std::vector tangents; Material* material; bool isDoubleSided; bool isBillboard; bool isShadowCaster; float depth; GLenum primitive_type; std::vector buffers; enum { // required buffer POSITION_BUFFER, // indices buffers INDICES_BUFFER, // optionnal buffers : NORMAL_BUFFER, TEXCOORD_BUFFER, TANGENT_BUFFER, // instanciation buffer INSTANCE_BUFFER, NB_BUFFERS }; int buffersId[NB_BUFFERS]; void addBuffer(Buffer *b, int bufferType); void clearBuffers(); GLuint vao; }; #endif // MESH_H