Meshes

Meshes are fundamental components in Raftel Engine that represent 3D geometry in your scenes. The mesh system handles loading, rendering, and manipulation of 3D models, supporting various file formats and providing tools for creating simple geometric shapes programmatically.

Key Features

  • Support for loading models from OBJ, FBX, DAE, STL, GLB and GLTF formats
  • Built-in primitive shape generation (cube, sphere, plane, cone, terrain)
  • Multi-threaded mesh loading for performance
  • Material assignment and texture mapping
  • Submesh handling for complex models
  • Automatic normal calculation

Architecture Overview

The mesh system in Raftel Engine consists of three main components:

Vertex Structure

The Vertex structure represents a single vertex in 3D space, containing position, normal, and texture coordinate attributes. Vertices are the building blocks of a mesh and are used to define its shape and surface properties.

Mesh Class

The Mesh class manages a collection of vertices and indices (defining triangles) along with associated materials. It handles loading mesh data from files, setting up OpenGL buffers (VAO, VBO, EBO), and rendering the mesh with specified shaders.

MeshFactory Class

The MeshFactory class provides factory methods for creating common geometric shapes (cube, sphere, plane, cone, terrain) without requiring external model files. This is useful for prototyping and creating simple objects.

Class Relationship Diagram

+----------------+               +----------------+
| Vertex         |               | Material       |
+----------------+               +----------------+
| - position     |               | - textures     |
| - normal       |<---------+    | - colors       |
| - texCoord     |          |    | - properties   |
+----------------+          |    +----------------+
                            |
                            |    +----------------+
+----------------+          |    | Engine         |
| MeshFactory    |          |    +----------------+
+----------------+          |    | - meshes       |
| - createCube() |          |    +----------------+
| - createSphere()|         |
| - createPlane()|          |
| - createCone() |          |
| - createTerrain()|        |
+----------------+          |
        |                   |
        v                   |
+----------------+          |
| Mesh           |----------+
+----------------+
| - submeshVertex |
| - submeshIndices|
| - materials    |
| - VAOs, VBOs, EBOs |
+----------------+
| + loadMesh()   |
| + draw()       |
| + setupMesh()  |
+----------------+
                    

Basic Usage

Here are some examples of how to use the Mesh system in Raftel Engine:

Loading a 3D Model

Loading a Mesh from File
#include "raftel/mesh.hpp"
#include "raftel/shader.hpp"

int main() {
  // Create a window and initialize OpenGL context (see Window System documentation)
  
  // Load a mesh from a file
  auto modelMesh = Raftel::Mesh::Create("assets/models/character.obj", true);
  
  // Create and set up a shader program
  auto shader = Raftel::ShaderProgram::Create("shaders/default.vert", "shaders/default.frag");
  
  // Create a material and assign it to the mesh
  auto material = std::make_shared();
  material->setAlbedoColor(glm::vec3(0.8f, 0.2f, 0.2f)); // Red color
  modelMesh->addMaterial(material);
  
  // Main rendering loop
  while (!window->ShouldClose()) {
    window->clear();
    
    shader->use();
    // Set up camera and transformation matrices...
    
    // Draw the mesh
    modelMesh->draw(*shader);
    
    window->swapBuffers();
  }
  
  return 0;
}

Creating a Primitive Shape

Creating and Rendering a Sphere
#include "raftel/mesh.hpp"
#include "raftel/shader.hpp"

int main() {
  // Create a window and initialize OpenGL context
  
  // Create a sphere with radius 2.0 and 32 segments
  auto sphereMesh = Raftel::MeshFactory::createSphere(2.0f, 32);
  
  // Create and set up a shader program
  auto shader = Raftel::ShaderProgram::Create("shaders/default.vert", "shaders/default.frag");
  
  // Create a material with a texture
  auto material = std::make_shared();
  auto texture = Raftel::Texture::loadTexture("assets/textures/earth.jpg");
  material->setAlbedo(texture);
  
  // Assign the material to the sphere mesh
  sphereMesh->setMaterial(material);
  
  // Main rendering loop
  while (!window->ShouldClose()) {
    window->clear();
    
    shader->use();
    // Set up camera and transformation matrices...
    
    // Draw the sphere
    sphereMesh->draw(*shader);
    
    window->swapBuffers();
  }
  
  return 0;
}

Vertex Structure Reference

struct Vertex

Represents a 3D vertex with attributes like position, normal, and texture coordinates.

Attributes

  • glm::vec3 position - The position of the vertex in 3D space.
  • glm::vec3 normal - The normal vector of the vertex for lighting calculations.
  • glm::vec2 texCoord - The texture coordinates of the vertex.

Mesh Class Reference

Constructors

Mesh()

Default constructor for the Mesh class.

Mesh(const std::string& filePath)

Constructs a mesh by loading from a file.

Parameters:

  • filePath - Path to the mesh file (OBJ, FBX, DAE, STL, GLB, GLTF)
Mesh(std::vector<std::vector<Vertex>> verticesPerSubmesh, std::vector<std::vector<unsigned int>> indicesPerSubmesh, std::vector<std::shared_ptr<Material>> mats)

Constructs a mesh with provided vertices, indices, and materials.

Parameters:

  • verticesPerSubmesh - Vector of vertex arrays for each submesh
  • indicesPerSubmesh - Vector of index arrays for each submesh
  • mats - Vector of materials

Static Factory Methods

static std::shared_ptr<Mesh> Create(const std::string& filePath, bool multithread)

Static factory method to create a mesh from a file.

Parameters:

  • filePath - Path to the mesh file
  • multithread - Whether to load the mesh in a separate thread

Returns: A shared pointer to the created mesh

Mesh Management Methods

bool loadMesh(const std::string& filePath)

Loads a mesh from a file.

Parameters:

  • filePath - Path to the mesh file

Returns: True if the mesh was loaded successfully, false otherwise

void setupMesh()

Sets up OpenGL buffers (VAO, VBO, EBO) for the mesh. This method should be called after loading the mesh or creating it from scratch.

void computeBoundingBox(glm::vec3& outMin, glm::vec3& outMax) const

Computes the axis-aligned bounding box (AABB) of the mesh.

Parameters:

  • outMin - Output parameter for the minimum corner of the bounding box
  • outMax - Output parameter for the maximum corner of the bounding box

Material Management Methods

void setMaterials(const std::vector<std::shared_ptr<Material>>& newMaterials)

Sets the materials for the mesh.

Parameters:

  • newMaterials - Vector of materials to apply to the mesh
void setMaterial(const std::shared_ptr<Material>& mat)

Sets a single material for the entire mesh.

Parameters:

  • mat - Material to apply to the mesh
void addMaterial(const std::shared_ptr<Material>& mat)

Adds a material to the mesh's material list.

Parameters:

  • mat - Material to add
std::shared_ptr<Material> GetMaterialByIndex(int index)

Retrieves a material by its index.

Parameters:

  • index - The index of the material to retrieve

Returns: A shared pointer to the material at the given index

std::vector<std::shared_ptr<Material>>& GetAllMaterials()

Retrieves all materials associated with the mesh.

Returns: A reference to the vector of materials

Rendering Methods

void draw(ShaderProgram& shader)

Renders the mesh using the specified shader program.

Parameters:

  • shader - The shader program to use for rendering
void setUniforms(GLuint shaderProgramID)

Sets the model, view, and projection uniform variables for the shader program.

Parameters:

  • shaderProgramID - The ID of the shader program
void renderMaterial(ShaderProgram& shader)

Renders the material properties using the specified shader.

Parameters:

  • shader - The shader program to use for rendering the material

MeshFactory Class Reference

static std::shared_ptr<Mesh> createPlane(float width, float height)

Creates a plane mesh with the specified dimensions.

Parameters:

  • width - The width of the plane
  • height - The height of the plane

Returns: A shared pointer to the created plane mesh

static std::shared_ptr<Mesh> createCube(float size)

Creates a cube mesh with the specified size.

Parameters:

  • size - The size of the cube (length of each edge)

Returns: A shared pointer to the created cube mesh

static std::shared_ptr<Mesh> createSphere(float radius, int segments)

Creates a sphere mesh with the specified radius and number of segments.

Parameters:

  • radius - The radius of the sphere
  • segments - The number of segments used to approximate the sphere's surface

Returns: A shared pointer to the created sphere mesh

static std::shared_ptr<Mesh> createCone(float radius, float height, int segments)

Creates a cone mesh with the specified radius, height, and number of segments.

Parameters:

  • radius - The radius of the base of the cone
  • height - The height of the cone
  • segments - The number of segments used to approximate the circular base

Returns: A shared pointer to the created cone mesh

static std::shared_ptr<Mesh> createTerrain(const char* heightMapFile, float size, float heightMultiplier, bool isCentered)

Creates a terrain mesh from a heightmap image.

Parameters:

  • heightMapFile - Path to the heightmap image
  • size - The size of each terrain grid cell
  • heightMultiplier - Multiplier for height values
  • isCentered - Whether the terrain should be centered at (0,0,0)

Returns: A shared pointer to the created terrain mesh

Supported File Formats

Raftel Engine's mesh system supports the following file formats:

OBJ (.obj)

Wavefront OBJ files are handled by Raftel Engine's native parser, which supports vertices, normals, texture coordinates, and materials (MTL).

FBX (.fbx)

Autodesk FBX files are supported through the Assimp library, preserving mesh data, materials, and texture coordinates.

COLLADA (.dae)

COLLADA files are supported through the Assimp library, maintaining mesh structure and material assignments.

STL (.stl)

STL files (both ASCII and binary) are supported through the Assimp library, though they only contain geometry without material information.

GLTF (.gltf)

GLTF format is supported for efficient transmission and loading of 3D models in applications, maintaining a rich scene representation including animations and node hierarchies.

GLB (.glb)

GLB format is the binary version of GLTF, supported for efficient streaming and loading of 3D models with embedded resources such as textures and shaders, commonly used in AR and VR platforms.

Best Practices

Advanced Features

Multi-Threaded Loading

For large models, Raftel Engine supports loading meshes in background threads to prevent freezing the main thread. This is enabled by passing true as the second parameter to Mesh::Create(). When using multi-threaded loading, the mesh will be loaded in the background, but you'll need to call setupMesh() on the main thread when loading is complete.

Submeshes

Complex models often consist of multiple parts that need different materials. Raftel Engine handles this with a submesh system, where each submesh can have its own vertices, indices, and material. When loading models from files, submeshes are automatically created based on the model's structure and material assignments.

MTL Material Loading

When loading OBJ files, Raftel Engine automatically loads associated MTL material files and applies the materials to the appropriate submeshes. This preserves the material assignments from the original model.

Related Topics

Loading 3D Meshes Tutorial

Step-by-step guide to loading and rendering 3D meshes in Raftel Engine.

Materials

Learn about the material system used to control the appearance of meshes.

Shaders

Understanding shaders that define how meshes are rendered.

Textures

Learn about textures that can be applied to mesh materials.