In the previous OpenGL case, we could tell that GLFrame could be handled in two different ways:

The observer is not moving, the object is moving and the observer is moving, the object is not moving and there is also the problem of pushing when we use the modelViewMatrix. (If there are mistakes in the article, please also point out!)

Explore the three methods involved in GLFrame:

  • SetupRC (initialization operation that initializes the initial position of the observer or object)
  • SpecialKeys (SpecialKeys that change the position of an observer or object)
  • RenderScene (RenderScene)

Here we declare two variables

// Viewer GLFrame cameraFrame; // object itself GLFrame objectFrame;Copy the code

1, SetupRC

  • The observer does not move, the object moves
// Move 15 units out of the screen, closer to the naked eye. Camerafame.MoveForward(-15.0f); camerafame.MoveForward(-15.0f); camerafame.Copy the code
  • The observer moves, the object does not move
// Move 15 units into the screen, further away from our eyes. Camerafame.MoveForward(15.0f);Copy the code

In the grand scheme of things, view transformations must be applied before any other model transformations can be applied. View transformation is the first transformation applied to the scene, through the object/observer movement on the Z axis, to determine the convenient position in the scene. By default, the observer in a perspective projection is positioned at the origin (0,0,0) and is looking into the screen in the negative direction of the z-axis. This is usually done using the moveForward method. The default orientation of moveForward is -z-axis, so moving a positive value into the screen and moving a positive value out of the screen is + z-axis. You need to pass in negative values.

2, SpecialKeys

  • The observer does not move, the object moves
RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f);Copy the code
  • The observer moves, the object does not move
Camerafame.RotateWorld(m3dDegToRad(-5.0), 1.0f, 0.0f, 0.0f);Copy the code

3, RenderScene

  • The observer does not move, the object moves

Because the observer changes position during initialization and the object moves. That’s why we have to record it when we render it

// push /* Because more than one data is pushed in, we need to use matrix multiplication, we need to convert the observer data into a matrix and then go in. ModelViewMatrix is initialized by pushing a null matrix, which is equivalent to copying the element matrix at the top of the stack. * and then pumped to the stack/modelViewMatrix PushMatrix (); M3DMatrix44f mCamreaMatrix = M3DMatrix44f mCamreaMatrix = M3DMatrix44f; cameraFrame.GetCameraMatrix(mCamreaMatrix); / / matrix multiplication in the top: (1) unit matrix * mCamreaMatrix = New_mCamreaMatrix modelViewMatrix. MultMatrix (mCamreaMatrix); // Initialize an object matrix and place it in M3DMatrix44f mObjectMatrix; objectFrame.GetMatrix(mObjectMatrix); //New_mCamreaMatrix * mObjectMatrix = New_mObjectMatrix modelViewMatrix.MultMatrix(mObjectMatrix); / / use shader shaderManager. UseStockShader (...). ; / / Draw torusBatch. The Draw (); . / / the stack modelViewMatrix PopMatrix ();Copy the code

  • The observer moves, the object does not move

Because the object doesn’t shift or anything like that, only the observer changes. All you have to do here is record the observer

/ / pressure stack, the observer directly to the pressure into the stack modelViewMatrix. PushMatrix (cameraFrame); / / use shader shaderManager. UseStockShader (...). ; / / Draw torusBatch. The Draw (); . / / the stack modelViewMatrix PopMatrix ();Copy the code

Matrix stack (rule) : Put the observer matrix first, then the object matrix, and finally the projection matrix

Thinking summary

Can I draw without the matrix stack?
  • If you draw a lot, you can’t do it without push and pop. Or other changes have effect on the mv, mv is global, didn’t you have also been affected, push the means that I take up first, I finished drawing, such as pop is my change from the global video out, keeping its original appearance, otherwise, they become jammed up, push pop is to draw change, also does not affect the overall environment, If you don’t use push or POP, then you can calculate mv data by yourself. For example, mv+ ABC-897 is drawn and MV-ABC +897 is completed. This is also ok, but it is just a rule change, there are rules to follow, even if you are familiar with it and the technology is very cool. I can calculate the value of each vertex when I say how to change a complex graph. After the change is complete, I can restore it, or I can calculate and restore it by myself. However, push and POP are done, why waste those brain cells?
What role does the MVP matrix play in the stack?
  • There’s only one MV, it’s global, everybody’s using it. Push –>mv * b * C * d * E * F * g –> pop –>mv. Push ->mv * ABC * 999 ->pop ->mv. Both A and B need their own changes. For example, A must be cross multiplied by bcdefG before it can be used as the last MV rendering of A. If you give A’s MV * B * C * D * E * F * G * ABC * 999 to B, it will be A mess. The final change you want will be yours

  • Mv * b * C * d * e * f * g mv * ABC * 999 mv * ABC * 999 It would be wrong to give mv * b * C * D * E * F * g * ABC * 999 to either A or B

  • Whose changes to whom, push pop combined OK