Suck the cat with code! This paper is participating in[Cat Essay Campaign].

I saw a new campaign on the Nuggets called “code sucking cats”, technical articles as long as they are related to cats.

For programmers who don’t own a cat, this is not easy.

But it doesn’t matter, use OpenGL image rendering to build your own cat!!

Model construction

The first thing you need to do is build a cat model, and if you can, you can build one in 3d software.

Or just download the free cat model like I did and import it into Blender 3D.

In Blender you can preview the cat model, or make some adjustments to it, and then export the model.

The model is loaded

The exported OBj file records the vertex information of the model, and then draws it out with OpenGL.

The asSIMP open source library is used here, which supports the parsing operation of various model files and parses the model into Mesh by means of it.

Mesh is defined as follows:

class Mesh {
public:
  /* Mesh Data */
  vector<Vertex> vertices;
  vector<unsigned int> indices;
  vector<Texture> textures;
  unsigned int VAO;
  // Omit some code
}
Copy the code

Mesh is equivalent to drawing a Mesh or facets on the model, which contains vertices, texture information and drawing index of the Mesh.

The Model Model is composed of this series of Mesh.

As shown in the figure above, the cat model is composed of small matrices, which can be understood as a mesh.

The definition of Model is as follows:

class Model
{
public:
  /* Model Data */
  vector<Texture> textures_loaded;    
  vector<Mesh> meshes;
  // Omit some code
}  
Copy the code

In the actual drawing process, the final drawing is done by Mesh.

    // draws the model, and thus all its meshes
 void Draw(Shader shader)
 {
   for(unsigned int i = 0; i < meshes.size(a); i++) meshes[i].Draw(shader);
 }
Copy the code

As can be seen from the figure, the mesh number of cat model is very large, resulting in very slow loading. The loading method is as follows:

  void loadModel(string const &path)
  {
    // Use the ASsimp library for loading
    const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
    // Check for errors
    if(! scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || ! scene->mRootNode)// if is Not Zero
    {
      cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;
      return;
    }
    // Get the folder where the model resides
    directory = path.substr(0, path.find_last_of('/'));

    // Start processing node by node from the root node
    processNode(scene->mRootNode, scene);
  }
Copy the code

Using ASsimp, you get a root node, and then you work your way down the root node.

  void processNode(aiNode *node, const aiScene *scene)
  {
    for(unsigned int i = 0; i < node->mNumMeshes; i++)
    {
      aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
      // Process the resulting aiMesh and assemble it into a defined Mesh data structure
      meshes.push_back(processMesh(mesh, scene));
    }
    // Process the child nodes
    for(unsigned int i = 0; i < node->mNumChildren; i++)
    {
      processNode(node->mChildren[i], scene); }}Copy the code

You can see a lot of for loops in the process, so the model files will be optimized later to speed up their loading.

Model rendering

Once you have the final Model, you can render it.

    // Model matrix adjusts the position and orientation of the model display
    glm::mat4 model = glm::mat4(1.0 f);
    model = glm::translate(model, glm::vec3(tranx_x, tranx_y, tranx_z));
    model = glm::rotate(model,glm::radians(90.0 f),glm::vec3(0.0.0.0.1.0));
    model = glm::scale(model, glm::vec3(0.5 f.0.5 f.0.5 f));    
    shader.setMatrix4fv("model", glm::value_ptr(model));
    ourModel.Draw(shader);
Copy the code

Since the model itself has a position and direction, the display may not be the desired observation direction, so we still need to adjust a model matrix.

Finally render to see the cat model effect.

summary

For easy observation, handle keyboard or mouse events, change the values of the model matrix, and lift the cat from different angles.

The current cat model is static and can only be adjusted using the keyboard, and only the move, zoom and rotate properties have been changed. The cat itself does not move.

In order for the cat to be able to move itself, it also needs to have the corresponding skeleton animation in the model. After having such a model, it will continue to iterate.

Follow the wechat public account audio and video development progress, see more follow-up content of the cat…