Mesh Drawing

The library handles mesh along two main type of classes:

Display a mesh

The process to display a primitive in a standard scene structure is the following.
struct scene_structure {
    // ...
    cgp::mesh_drawable cube_drawable; 
    // ...
}

void scene_structure::initialize()
{
    // ...

    // Create a temporary mesh structure
    mesh cube = mesh_primitive_cube();
    //   - Create the primitive as mesh


    // Initialize the mesh_drawable from the mesh
    cube_drawable.initialize_data_on_gpu(cube);
    // This initialize the OpenGL buffers on cube_drawable from the data stored in the variable cube
}


void scene_structure::display_frame()
{
    // ...

    draw(shape, environment);
    // Note: environment is a variable that contains the scene parameters
    //  ex. camera, light, etc.
}
assets/cube.jpg
The position, orientation, color and shading of the shape can be modified using the parameters attached to the mesh_drawable class. These parameters are sent as uniform values to the default shader.
void scene_structure::display()
{
    // ...

	// change the color parameter
	shape.material.color = { 1.0f, 1.0f, 0.8f};
	// change the translation parameter
	shape.model.translation = { 1.5f,0,0 };

	// the current color is used when calling draw(...)
	draw(shape, environment); 

	// a wireframe call is also available by default
	draw_wireframe(shape, environment);
}
assets/cube_offset.jpg

Draw call

The display a drawable entity follows the main general steps: Set current shader, send uniform parameters, display calls. Two variables are needed for the draw(...) function
The draw call of a mesh_drawable element can be summarized as follows

draw(drawable, environment)

1) Set current shader attached to drawable element
glUseProgram( drawable.shader )

2.a) Send uniforms parameters attached to the drawable element
glUniform( drawable.[parameters] ) ... on transform and shading values

2.b) Send uniforms parameters attached to the environment
glUniform( environment.[parameters] ) ...

3) Set texture of the drawable element
glBindTexture(GL_TEXTURE_2D, drawable.texture)

4) Draw calls on the drawable vbo (data already stored on the GPU)
glBindVertexArray( drawable.vao )
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.connectivity)
glDrawElements(GL_TRIANGLES)

5) Cleaning buffers state
glBindVertexArray(0)
glBindTexture(GL_TEXTURE_2D, 0)

Environment variable

The environment structure describes the variables and states that are necessary to draw an element and is used by the shader, but does conceptually depends on the global scene rather than an individual element.

Pre-existing scene provide a typical default basic environment
struct environment_structure : environment_generic_structure
{

	// Color of the background of the scene
	vec3 background_color = {1,1,1}; // Used in the main program

	// The position/orientation of a camera that can rotates freely around a specific position
	mat4 camera_view;

	// A projection structure (perspective or orthogonal projection)
	mat4 camera_projection;

	// The position of a light
	vec3 light = {1,1,1};

};
The parameters of the environment variable are sent as uniform values to the shader for each displayed object (via environment.send_opengl_uniform(shader)). The value of these parameters can be modified at each frame to represent an animated camera.
During the draw call, the environment parameters are sent to the shader via the function
void opengl_uniform(GLuint shader, scene_environment const& scene)
Custom environment can be defined by the user in adding new variables and setting an associated opengl_uniform function.
A generic type uniform_generic_structure can also be used to add new uniform parameters to an existing environment structure without re-definition.
- uniform.hpp
13_opengl/uniform/uniform.hpp
struct environment_structure
{

    // ...

    // generic container for uniform values (pairs of string/value)
    uniform_generic_structure uniform_generic;
};

GUI

The interface is using ImGui library.

An example of simple use of the gui is the following
// In scene.hpp
struct gui_parameters {
	bool display_frame      = true;
	bool display_wireframe  = false;
};
// In scene.cpp
void scene_structure::display_gui()
{
	ImGui::Checkbox("Frame", &gui.display_frame);
	ImGui::Checkbox("Wireframe", &gui.display_wireframe);
	ImGui::SliderFloat("Translation", &shape.model.translation.x, -2.0f, 2.0f);
}
// In scene.cpp
void scene_structure::display_frame()
{
    // ...
	draw(shape, environment); 
	if(gui.display_wireframe)
		draw_wireframe(shape, environment);
}