245 lines
7.8 KiB
C++
245 lines
7.8 KiB
C++
#ifndef MESH_H
|
|
#define MESH_H
|
|
|
|
#include "glew.h"
|
|
#include <vector>
|
|
#include <glm/vec3.hpp>
|
|
#include <glm/vec2.hpp>
|
|
|
|
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<glm::vec3> positions3D;
|
|
std::vector<glm::vec3> normals;
|
|
|
|
// 2D public data
|
|
std::vector<glm::vec2> positions2D;
|
|
|
|
// public data common to 2D and 3D
|
|
std::vector<glm::vec2> texCoords;
|
|
std::vector<glm::vec3> instances_offsets;
|
|
std::vector<GLuint> 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> tangents;
|
|
|
|
Material* material;
|
|
bool isDoubleSided;
|
|
bool isBillboard;
|
|
bool isShadowCaster;
|
|
float depth;
|
|
|
|
GLenum primitive_type;
|
|
|
|
std::vector<Buffer*> 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
|