MinGfx Toolkit  1.0
A minimal library for writing cross-platform (Windows, OSX, linux) graphics programs.
Public Member Functions | List of all members
mingfx::Mesh Class Reference

Detailed Description

A triangle mesh data structure that can be rendered with a ShaderProgram like DefaultShader.

The mesh can be created algorithmically by adding triangles one at a time or it can be loaded from an .obj file.

Vertices are required – you cannot have a mesh without vertices, but other attributes (normals, colors, texture coordinates) are optional. When Draw() is called the mesh will automatically set these other attributes if available.

Example of loading from a file:

// during initialization
Mesh m;
m.LoadFromOBJ(Platform::FindMinGfxDataFile("teapot.obj"));
// also create a shader to draw it.
DefaultShader s;
// later to draw
Matrix4 M;
Matrix4 V = Matrix4::LookAt(Point3(0,0,3), Point3(0,0,0), Vector3(0,1,0));
Matrix4 P = Matrix4::Perspective(60.0, aspect_ratio(), 0.1, 10.0);
s.Draw(M, V, P, m, DefaultShader::MaterialProperties());
static Matrix4 Perspective(float fov_y_in_degrees, float aspect_ratio, float near_plane_dist, float far_plane_dist)
Returns a perspective projection matrix equivalent to the one gluPerspective creates.
static Matrix4 LookAt(Point3 eye, Point3 target, Vector3 up)
Returns a view matrix that centers the camera at the 'eye' position and orients it to look at the des...
Mesh()
Creates an empty mesh.
static std::string FindMinGfxDataFile(const std::string &basename)
Searches for a data file that ships with MinGfx.

Example of creating a mesh algorithmically:

Mesh mesh1;
int tri_id;
// add a first triangle
tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,0,0), Point3(1,1,0));
// set attributes for the vertices
mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,1), Point2(1,0));
// add a second triangle and attributes
tri_id = mesh1.AddTriangle(Point3(0,0,0), Point3(1,1,0), Point3(0,1,0));
mesh1.SetNormals(tri_id, Vector3(0,0,1), Vector3(0,0,1), Vector3(0,0,1));
mesh1.SetTexCoords(tri_id, 0, Point2(0,1), Point2(1,0), Point2(0,0));
// call this when done to save to the GPU
mesh1.UpdateGPUMemory();
// then you can draw the same way as in the previous example.

In the mode used above where you add one triangle at a time there is no way to reuse vertices in multiple triangles. If you need to do this for efficiency or other reasons, then you can use an indexed faces mode where you set the mesh data structures directly.

Example of creating a mesh that renders in an indexed faces mode:

std::vector<unsigned int> indices;
std::vector<Point3> vertices;
std::vector<Vector3> normals;
std::vector<Point2> texcoords;
// four vertices, each requires 3 floats: (x,y,z)
vertices.push_back(Point3(0,0,0));
vertices.push_back(Point3(1,0,0));
vertices.push_back(Point3(1,1,0));
vertices.push_back(Point3(0,1,0));
// four normals, each requires 3 floats: (x,y,z)
normals.push_back(Vector3(0,0,1));
normals.push_back(Vector3(0,0,1));
normals.push_back(Vector3(0,0,1));
normals.push_back(Vector3(0,0,1));
// four texture coords, each requires 2 floats: (u,v)
texcoords.push_back(Point2(0,1));
texcoords.push_back(Point2(1,1));
texcoords.push_back(Point2(1,0));
texcoords.push_back(Point2(0,0));
// indices into the arrays above for the first triangle
indices.push_back(0);
indices.push_back(1);
indices.push_back(2);
// indices for the second triangle, note some are reused
indices.push_back(0);
indices.push_back(2);
indices.push_back(3);
Mesh mesh1;
mesh1.SetVertices(vertices);
mesh1.SetNormals(normals);
mesh1.SetTexCoords(0, texcoords);
mesh1.SetIndices(indices);
mesh1.UpdateGPUMemory();
// then you can draw the same way as in the previous example.

Definition at line 127 of file mesh.h.

#include <mesh.h>

Public Member Functions

 Mesh ()
 Creates an empty mesh. More...
 
 Mesh (const Mesh &other)
 Copies all data and sets GPU dirty bit for the new mesh. More...
 
virtual ~Mesh ()
 
void LoadFromOBJ (const std::string &filename)
 This reads a mesh stored in the common Wavefront Obj file format. More...
 
int AddTriangle (Point3 v1, Point3 v2, Point3 v3)
 Adds a triangle to the mesh datastructure and returns a triangle ID. More...
 
void UpdateTriangle (int triangle_id, Point3 v1, Point3 v2, Point3 v3)
 Updates the vertex positions for a triangle that has already been added to the mesh. More...
 
void SetNormals (int triangle_id, Vector3 n1, Vector3 n2, Vector3 n3)
 Sets the normals for the three vertices of a triangle that has already been added to the mesh. More...
 
void SetColors (int triangle_id, Color c1, Color c2, Color c3)
 Sets per-vertex colors for the three vertices of a triangle that has already been added to the mesh. More...
 
void SetTexCoords (int triangle_id, int texture_unit, Point2 uv1, Point2 uv2, Point2 uv3)
 Sets the texture coordinates for the three vertices of a triangle that has already been added to the mesh. More...
 
void SetVertices (const std::vector< Point3 > &verts)
 Sets the vertex array for the mesh directly. More...
 
void SetNormals (const std::vector< Vector3 > &norms)
 Sets the normal array for the mesh directly. More...
 
void SetColors (const std::vector< Color > &colors)
 Sets the per-vertex colors array for the mesh directly. More...
 
void SetTexCoords (int texture_unit, const std::vector< Point2 > &tex_coords)
 Sets a texture coordinates array for the mesh directly. More...
 
void SetIndices (const std::vector< unsigned int > index_array)
 Sets the indices into the vertex array to use to create the triangles. Each consecutive set of 3 indices forms one triangle: (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ... More...
 
void SetInstanceTransforms (const std::vector< Matrix4 > &xforms)
 
void SetVertices (float *verts_array, int num_verts)
 Sets the vertex array for the mesh directly. Vertices are stored as (x,y,z), (x,y,z), (x,y,z), ... This version of the function accepts a C-style array rather than std::vector<> More...
 
void SetNormals (float *norms_array, int num_norms)
 Sets the normal array for the mesh directly. Normals are stored as (x,y,z), (x,y,z), (x,y,z), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<> More...
 
void SetColors (float *colors_array, int num_colors)
 Sets the per-vertex colors array for the mesh directly. Colors are stored as (r,g,b,a), (r,g,b,a), (r,g,b,a), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<> More...
 
void SetTexCoords (int texture_unit, float *tex_coords_array, int num_tex_coords)
 Sets a texture coordinates array for the mesh directly. Tex coords are stored as (u,v), (u,v), (u,v), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<> More...
 
void SetIndices (unsigned int *index_array, int num_indices)
 Sets the indices into the vertex array to use to create the triangles. Each consecutive set of 3 indices forms one triangle: (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ... This version of the function accepts a C-style array rather than std::vector<> More...
 
void UpdateGPUMemory ()
 This copies the entire mesh data structure to a vertex array in GPU memory, which must happen before you can draw the mesh. More...
 
void Draw ()
 This sends the mesh vertices and attributes down the graphics pipe using glDrawArrays() for the non-indexed mode and glDrawElements() for the indexed mode. More...
 
void CalcPerFaceNormals ()
 This (re)calculates the normals for the mesh and stores them with the mesh data structure. More...
 
void CalcPerVertexNormals ()
 This (re)calculates the normals for the mesh and stores them with the mesh data structure. More...
 
void BuildBVH ()
 This (re)calculates a Bounding Volume Hierarchy for the mesh, which can be used together with Ray::FastIntersectMesh() to do faster ray-mesh intersection testing. More...
 
BVHbvh_ptr ()
 Returns a pointer to the underlying BVH data structure. More...
 
int num_vertices () const
 The total number of vertices in the mesh. More...
 
Point3 read_vertex_data (int vertex_id) const
 Read only access to the vertex position data. Data are returned as a Point3. Indexed by vertex number. Also see num_vertices(). Use the SetVertices() function to set (or edit) vertex data. More...
 
Vector3 read_normal_data (int vertex_id) const
 Read only access to per-vertex normal data. Data are returned as a Vector3. Indexed by vertex number. Also see num_vertices(). Use the SetNormals() function to set (or edit) per-vertex normal data. More...
 
Color read_color_data (int vertex_id) const
 Read only access to per-vertex color data. Data are returned as a Color. Indexed by vertex number. Also see num_vertices(). Use the SetColors() function to set (or edit) per-vertex color data. More...
 
Point2 read_tex_coords_data (int texture_unit, int vertex_id) const
 Read only access to per-vertex texture coordinates data. Data are returned as a Point2. Indexed by vertex number. Also see num_vertices(). Use the SetTexCoords() function to set (or edit) per-vertex tex coords. More...
 
int num_triangles () const
 The total number of triangles in the mesh. More...
 
std::vector< unsigned int > read_triangle_indices_data (int triangle_id) const
 Read only access to the indices that make up a particular triangle. Data are returned as a 3-element array. More...
 

Constructor & Destructor Documentation

◆ Mesh() [1/2]

mingfx::Mesh::Mesh ( )

Creates an empty mesh.

◆ Mesh() [2/2]

mingfx::Mesh::Mesh ( const Mesh other)

Copies all data and sets GPU dirty bit for the new mesh.

◆ ~Mesh()

virtual mingfx::Mesh::~Mesh ( )
virtual

Member Function Documentation

◆ AddTriangle()

int mingfx::Mesh::AddTriangle ( Point3  v1,
Point3  v2,
Point3  v3 
)

Adds a triangle to the mesh datastructure and returns a triangle ID.

The ID should then be used as the first argument for follow-on calls to SetNormals(), SetColors(), and SetTexCoords(). The vertices must be specified in counter-clockwise order so that the normal of the triangle can be determined following the right-hand rule.

◆ BuildBVH()

void mingfx::Mesh::BuildBVH ( )

This (re)calculates a Bounding Volume Hierarchy for the mesh, which can be used together with Ray::FastIntersectMesh() to do faster ray-mesh intersection testing.

◆ bvh_ptr()

BVH* mingfx::Mesh::bvh_ptr ( )

Returns a pointer to the underlying BVH data structure.

If the data struture has not yet been build or needs to be updated due to a change in the geometry of the mesh, then the BVH is recalculated before returning the pointer.

◆ CalcPerFaceNormals()

void mingfx::Mesh::CalcPerFaceNormals ( )

This (re)calculates the normals for the mesh and stores them with the mesh data structure.

It assumes a faceted mesh, like a cube, where each triangle has separate vertices. The normal is calculated for each triangle face and then the result is associated with each vertex that makes up the triangle. If you have a smooth mesh where vertices are shared between multiple faces then use CalcPerVertexNormals() instead.

◆ CalcPerVertexNormals()

void mingfx::Mesh::CalcPerVertexNormals ( )

This (re)calculates the normals for the mesh and stores them with the mesh data structure.

It assumes a smooth mesh, like a sphere, where each vertex belongs to one or more triangles. Each vertex normal is calculated as a weighted sum of the face normals for adjacent faces. The weighting is based upon the relative areas of the neighboring faces (i.e., a large neighboring triangle contributes more to the vertex normal than a small one).

◆ Draw()

void mingfx::Mesh::Draw ( )

This sends the mesh vertices and attributes down the graphics pipe using glDrawArrays() for the non-indexed mode and glDrawElements() for the indexed mode.

This is just the geometry – for anything to show up on the screen, you must already have a ShaderProgram enabled before calling this function.

◆ LoadFromOBJ()

void mingfx::Mesh::LoadFromOBJ ( const std::string &  filename)

This reads a mesh stored in the common Wavefront Obj file format.

The loader here is simplistic and not guaranteed to work on all valid .obj files, but it should work on many simple ones. UpdateGPUMemory() is called automatically after the model is loaded.

◆ num_triangles()

int mingfx::Mesh::num_triangles ( ) const

The total number of triangles in the mesh.

◆ num_vertices()

int mingfx::Mesh::num_vertices ( ) const

The total number of vertices in the mesh.

◆ read_color_data()

Color mingfx::Mesh::read_color_data ( int  vertex_id) const

Read only access to per-vertex color data. Data are returned as a Color. Indexed by vertex number. Also see num_vertices(). Use the SetColors() function to set (or edit) per-vertex color data.

◆ read_normal_data()

Vector3 mingfx::Mesh::read_normal_data ( int  vertex_id) const

Read only access to per-vertex normal data. Data are returned as a Vector3. Indexed by vertex number. Also see num_vertices(). Use the SetNormals() function to set (or edit) per-vertex normal data.

◆ read_tex_coords_data()

Point2 mingfx::Mesh::read_tex_coords_data ( int  texture_unit,
int  vertex_id 
) const

Read only access to per-vertex texture coordinates data. Data are returned as a Point2. Indexed by vertex number. Also see num_vertices(). Use the SetTexCoords() function to set (or edit) per-vertex tex coords.

◆ read_triangle_indices_data()

std::vector<unsigned int> mingfx::Mesh::read_triangle_indices_data ( int  triangle_id) const

Read only access to the indices that make up a particular triangle. Data are returned as a 3-element array.

◆ read_vertex_data()

Point3 mingfx::Mesh::read_vertex_data ( int  vertex_id) const

Read only access to the vertex position data. Data are returned as a Point3. Indexed by vertex number. Also see num_vertices(). Use the SetVertices() function to set (or edit) vertex data.

◆ SetColors() [1/3]

void mingfx::Mesh::SetColors ( const std::vector< Color > &  colors)

Sets the per-vertex colors array for the mesh directly.

◆ SetColors() [2/3]

void mingfx::Mesh::SetColors ( float *  colors_array,
int  num_colors 
)

Sets the per-vertex colors array for the mesh directly. Colors are stored as (r,g,b,a), (r,g,b,a), (r,g,b,a), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<>

◆ SetColors() [3/3]

void mingfx::Mesh::SetColors ( int  triangle_id,
Color  c1,
Color  c2,
Color  c3 
)

Sets per-vertex colors for the three vertices of a triangle that has already been added to the mesh.

◆ SetIndices() [1/2]

void mingfx::Mesh::SetIndices ( const std::vector< unsigned int >  index_array)

Sets the indices into the vertex array to use to create the triangles. Each consecutive set of 3 indices forms one triangle: (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ...

◆ SetIndices() [2/2]

void mingfx::Mesh::SetIndices ( unsigned int *  index_array,
int  num_indices 
)

Sets the indices into the vertex array to use to create the triangles. Each consecutive set of 3 indices forms one triangle: (v1,v2,v3), (v1,v2,v3), (v1,v2,v3), ... This version of the function accepts a C-style array rather than std::vector<>

◆ SetInstanceTransforms()

void mingfx::Mesh::SetInstanceTransforms ( const std::vector< Matrix4 > &  xforms)

◆ SetNormals() [1/3]

void mingfx::Mesh::SetNormals ( const std::vector< Vector3 > &  norms)

Sets the normal array for the mesh directly.

◆ SetNormals() [2/3]

void mingfx::Mesh::SetNormals ( float *  norms_array,
int  num_norms 
)

Sets the normal array for the mesh directly. Normals are stored as (x,y,z), (x,y,z), (x,y,z), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<>

◆ SetNormals() [3/3]

void mingfx::Mesh::SetNormals ( int  triangle_id,
Vector3  n1,
Vector3  n2,
Vector3  n3 
)

Sets the normals for the three vertices of a triangle that has already been added to the mesh.

◆ SetTexCoords() [1/3]

void mingfx::Mesh::SetTexCoords ( int  texture_unit,
const std::vector< Point2 > &  tex_coords 
)

Sets a texture coordinates array for the mesh directly.

◆ SetTexCoords() [2/3]

void mingfx::Mesh::SetTexCoords ( int  texture_unit,
float *  tex_coords_array,
int  num_tex_coords 
)

Sets a texture coordinates array for the mesh directly. Tex coords are stored as (u,v), (u,v), (u,v), ... following the same ordering as was used for SetVertices(). This version of the function accepts a C-style array rather than std::vector<>

◆ SetTexCoords() [3/3]

void mingfx::Mesh::SetTexCoords ( int  triangle_id,
int  texture_unit,
Point2  uv1,
Point2  uv2,
Point2  uv3 
)

Sets the texture coordinates for the three vertices of a triangle that has already been added to the mesh.

The first textureUnit is 0, and you should always use 0 for this parameter unless you are doing multi-texturing.

◆ SetVertices() [1/2]

void mingfx::Mesh::SetVertices ( const std::vector< Point3 > &  verts)

Sets the vertex array for the mesh directly.

◆ SetVertices() [2/2]

void mingfx::Mesh::SetVertices ( float *  verts_array,
int  num_verts 
)

Sets the vertex array for the mesh directly. Vertices are stored as (x,y,z), (x,y,z), (x,y,z), ... This version of the function accepts a C-style array rather than std::vector<>

◆ UpdateGPUMemory()

void mingfx::Mesh::UpdateGPUMemory ( )

This copies the entire mesh data structure to a vertex array in GPU memory, which must happen before you can draw the mesh.

For large meshes, this can take some time, so you may want to call this during initialization immediately after generating the mesh. If you do not, it will be called automatically for you the first time Draw() is called. If the mesh contains normals, per- vertex colors and/or texture coordinates these are added as attributes within the vertex array.

◆ UpdateTriangle()

void mingfx::Mesh::UpdateTriangle ( int  triangle_id,
Point3  v1,
Point3  v2,
Point3  v3 
)

Updates the vertex positions for a triangle that has already been added to the mesh.


The documentation for this class was generated from the following file: