Animation in Graphics - Introduction
Download code base
Download any of these archive containing all the necessary codes- - On Github: [ https://github.com/drohmer/epita_ani3d_lab_code ]
- - Or via direct archive download:
-
- - [ epita_ani3d_lab_code.zip ]
- - [ epita_ani3d_lab_code.tar.gz ]
-
Make sure you can compile and run the scene in
scenes_ani3d/00_introduction/
. -
- If needed, you can follow these detailed instructions for Installation and Compilation.
- - Your C++ compiler should be compatible with C++14.
- - Glad is used to load function for OpenGL 3.3.
- - GLFW is used to create a window and handle mouse/key events.
- - ImGUI is used to handle GUI.
Introductory scene
-
The first introductory scene is available in the directory
scenes_ani3d/00_introduction/
-
-
- Each exercise is described as a unique program (with its own main) defined in the
scenes/
directory. -
- A
CMakeLists.txt
is associated to each program for its compilation (+ a Makefile for Unix systems). -
- (you need to adapt the path of the compilation instructions to the directory of the CMakeLists.txt for each exercise)
-
- Each exercise is described as a unique program (with its own main) defined in the
- Once executed, you should observe a basic scene as seen below with rotating cylinder, cube, and curve (some details may vary).
-
-
- Note that the source code of the scene is fully described in the files
src/main.cpp
andsrc/scene.cpp
(andsrc/scene.hpp
). -
main.cpp
file contains common elements through all the exercises (general set up of the scene, animation loop, basic handling of the keyboard/mouse input). Usually you won't have to edit themain.cpp
. -
scene.cpp
and (scene.hpp
) describe the specific content of the scene exercise. You may have to do your edit in this file.
-
- Note that the source code of the scene is fully described in the files
Information on the library (only general information, no exercise)
CGP library provides a set of functionalities to ease 3D graphics programming such as- - Structure for 3D vectors and matrices (and 2D, 4D).
- - Object structure ready to be displayed with OpenGL (Meshes, lines, etc) and their associated shaders.
- - Easy and secured storage for buffers of elements.
- - 3D scene manipulation: Mouse controlled camera
cgp::
Use of the code library
First observe the filemain.cpp
. You should recognize the general organization of the program, in particular the setup stage, and the animation loop stage. Note where the two main methods scene.initialize()
and scene.display_frame()
are called, and their implementation in the file scene.cpp
. In the following you will only modify code in the file scene.cpp (and scene.hpp).
-
> Change the rotation (parameterized by and axis and an angle) from some of the object within the scene in the function
display_frame()
. -
-
- The pre-existing function
rotation_axis_angle(axis_of_rotation, angle_of_rotation);
from the CGP library can be used to generate a structure cgp::rotation_transform from a given 3D axis (cgp::vec3) and scalar angle (float) in radians. - - The structure cgp::vec3 implements a model of 3D vector with (x,y,z) coordinates.
-
- You can apply most of the basic operations between vec3 and mat3 using mathematical operators (+,-,*,/).
- - The structure rotation_transform allowing to generate and manipulate a rotation. The rotation is stored internaly as a quaternion, and can be manipulated similarily to a matrix when applied on a vector.
- The rotation is stored in the variable "model" of a mesh_drawable structure. model stores an affine transformation which is used as uniform variable when the shape is displayed.
-
- The pre-existing function
- Note that there is two type of "mesh" structures in use
-
- - cgp::mesh storing buffer on data (per vertex: position, normal, uv, color, and triangle connectivity) on CPU
-
- This structure allows to conveniently access to all the data defining a mesh from the C++ code. However these data are not on the GPU, so a mesh cannot be directly displayed.
-
- - cgp::mesh_drawable storing VBOs associated to these buffer once sent on the GPU memory (in the sub-structure mesh_drawable_gpu_data) as well as its VAO. The structure also stores uniform parameters that are sent to the shader at every draw call. A default shader and texture id are also be stored with the structure.
-
- This structure only stores the index corresponding to elements on GPU. You cannot modify individual per-vertex elements easily from this structure.
-
-
Remark: a mesh_drawable can be automatically generated/initialized from a mesh structure in calling the construction
mesh_drawable.initialize_data_on_gpu(meshName)
. However, you cannot create a mesh from a mesh_drawable.
-
Remark: a mesh_drawable can be automatically generated/initialized from a mesh structure in calling the construction
Adding a sphere
In this first part we display a new sphere to the scene.- > Add the class variable to scene_structure class (in the file scene.hpp)
cgp::mesh_drawable sphere;
- In this example, cgp:: is optional as the header file already indicated "using cgp::mesh_drawable;" in its beginning.
- > Initialize this variable in the file scene.cpp in the initialize() function as a sphere of radius 0.5
mesh sphere_mesh = mesh_primitive_sphere(0.5f); sphere.initialize_data_on_gpu(sphere_mesh);
- (or variant: simply in one line without explicitely storing the mesh variable)
sphere.initialize_data_on_gpu(mesh_primitive_sphere(0.5f));
- > Display this sphere in the display_frame() function with the following code
draw(sphere, environment);
- > Compile, run, and observe the sphere in the 3D scene.
- Note: You can set geometric transformation using the uniform properties of the mesh_drawable structure (reminder: uniform are parameters passed to the shaders).
-
- sphere.model.translation/rotation/scaling = ... (see example on the other displayed shapes)
- Note also that unless specified explicitely, the default shader associated to the mesh_drawable structure is used.
- The three trasformations: translation, rotation, and scaling are simply variables that you can write on. By default, their values are respectively, (0,0,0), the identity, and 1. The content of the variables are used (as uniform values in the shader) when the draw call is used.
- > Add the following line before calling draw on the sphere and observe that the color (as well as any other uniform parameter) can be changed through time in modifying its value at every frame.
sphere.material.color = vec3(1+std::cos(time), 1+std::sin(time), 2.0)/2.0f;
Checkbox interface
We will now add a GUI checkbox (button that can be checked) to activate/deactivate the wireframe display of the sphere.- > Add the following variable in the definition of the structure struct gui_parameters (in the file scene.hpp) to store a boolean state indicating when the wireframe should be displayed or not
bool display_wireframe = false;
- > In the function display_gui() (in scene.cpp) add a Checkbox (handled by ImGui library) and link it (through its adress) to the variable display_wireframe in adding this line of code
ImGui::Checkbox("Wireframe", &gui.display_wireframe);
- In running the code, the checkbox should appear. Every time you select/unselect it, the value of the variable display_wireframe change from true to false but doesn't change yet anything in the 3D display.
- > Add the following code in the display_frame function
if (gui.display_wireframe) draw_wireframe(sphere, environment, { 1,1,0 });
- Check that you can now interactively display the wireframe representation of the sphere.
Texture
Textures images can also be associated to surfaceNote that the per-vertex uv coordinates need to be defined correctly to get the mapping of the image on the surface.
- > Update the initialization of your shape variable with the following two lines code and observe that your surface should now be textured
// Reset the color of the shape to white (only the texture image will be seen) shape_visual.material.color = {1,1,1}; // Load the image and associate the texture id to the structure shape_visual.texture.load_and_initialize_texture_2d_on_gpu(project::path+"assets/squirrel.jpg");
- Note: The variable project::path is automatically filled in the beginning of the program and tries to adapt the relative path to find the assets directory. If you omit it, you need to run your executable program from the root directory (where you can find the assets/ and shaders/ directory).