OpenGL | OpenGL matrix operation (under the view model matrix)

There are generally many matrix transformation operations in the opengl scene, and the commands to control these operations mainly use the glMatrixMode function.

The modelview matrix is ​​called when scaling an object or viewing it from a different perspective. It mainly involves three functions:

glTranslate、glRotate、glScale。

1. Translate glTranslatef

1. Introduction to glTranslatef

void WINAPI glTranslatef(
   GLfloat x,
   GLfloat y,
   GLfloat z
);
  • Translate x units along the positive direction of the X axis (x is a signed number)

  • Translate y units along the positive direction of the Y axis (y is a signed number)

  • Translate z units along the positive direction of the Z axis (z is a signed number)

2. glTranslatef application

We all know: When we use OpenGL to draw graphics, if the third parameter of glVertex3f>=0, the screen will not be able to draw the effect. As the following code:

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);
    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, 0.0f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, 0.0f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, 0.0f);
    glEnd();
}

So in order to obtain the correct drawing effect, in addition to changing the third parameter of glVertex3f to a negative number, we can also use matrix conversion to achieve it.

void Init()
{
    glMatrixMode(GL_PROJECTION);//将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW); //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();           //把矩阵设为单位矩阵
    glTranslatef(0, 0, - 1.5f);//此时ModedlViewMatrix就可以让之后的所有数据都带上一个-1.5的Z方向的偏移
}

Second, rotate glRotatef

1. Introduction to glRotatef

void WINAPI glRotatef(
   GLfloat angle,
   GLfloat x,
   GLfloat y,
   GLfloat z
);

The glRotatef function rotates the matrix counterclockwise by an angle from the point (0,0,0) to the point (x,y,z) for the previous matrix.

2. glRotatef application

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵
    glRotatef(30, 0, 0, 1);         //此时ModedlViewMatrix就可以让之后的所有数据都绕(0,0,1)旋转30度
}

3. Scale glScalef

1. Introduction to glScalef

void WINAPI glScalef(
   GLfloat x,
   GLfloat y,
   GLfloat z
);

The glScalef function generates general scaling along the x , y , and z axes.

2. glScalef application

Analyze with the third parameter:

(1) When the third parameter of glVertex3f is 0, when the matrix translation is performed by glTranslatef, there will be a graphic scaling effect on the drawing screen after using glScalef.

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵

    glTranslatef(0, 0, - 1.5f);    //平移

    glScalef(0.1f, 0.1f, 0.1f);
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, 0.0f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, 0.0f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, 0.0f);
    glEnd();
}

As above code:

When commenting glScalef(0.1f, 0.1f, 0.1f);

When adding glScalef(0.1f, 0.1f, 0.1f);

(2) When the third parameter of glVertex3f is not 0, and the matrix translation is not performed through glTranslatef, because glScalef affects the third parameter of glVertex3f, the drawing of the point is close to the camera, so after drawing, the visual effect There is no graphical scaling effect on it. As the following code: add or comment glScalef(0.1f, 0.1f, 0.1f); after the screen effect remains unchanged.

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵
    glScalef(0.1f, 0.1f, 0.1f);
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    //绘制独立的三角形
    glBegin(GL_TRIANGLES);        //注意是逆时针绘制
    glColor4ub(0, 0, 255, 255);   //蓝
    glVertex3f(-0.2f, -0.2f, -1.5f);

    glColor4ub(255, 0, 0, 255);   //红
    glVertex3f(0.2f, -0.2f, -1.5f);

    glColor4ub(0, 255, 0, 255);   //绿
    glVertex3f(0.0f, 0.2f, -1.5f);
    glEnd();
}

4. Push the stack out of the stack

Since openGL has only one coordinate system, you should pay attention to saving the coordinates of the current coordinate system so that you can return after drawing. As in the code below: drawing A in this way will not affect other parts.

glPushMatrix()
//坐标变换。。。
//画好物体A
glPopMatrix();
//继续新的代码

1.glPushMatrix & glPopMatrix

All operations on the matrix are performed on the top of the matrix stack. The current matrix is ​​the top element of the matrix stack, and the transformation operations such as translation and rotation on the current matrix are also modifications to the top matrix of the stack. So if we call glPushMatrix() before the transformation, the current state will be pushed into the second layer, and the matrix at the top of the stack is also the same as the second layer.

After a series of transformations, the matrix at the top of the stack is modified. When glPopMatrix() is called at this time, the matrix at the top of the stack is popped up and restored to its original state.

2. Take a chestnut

(1) Code

void Init()
{
    glMatrixMode(GL_PROJECTION);     //将当前矩阵指定为投影矩阵,对投影矩阵操作
    gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵,并且用这个矩阵乘以当前矩阵
    glMatrixMode(GL_MODELVIEW);      //将当前矩阵指定为模型视图矩阵,对模型视图矩阵操作
    glLoadIdentity();                //把矩阵设为单位矩阵 
}

void Draw()
{
    glClearColor(1, 1, 1, 1.0f);  //白色背景
    glClear(GL_COLOR_BUFFER_BIT);

    glLoadIdentity();                //重置矩阵设为单位矩阵

     //glTranslatef使两个同位置的三角形分开
    glPushMatrix();
         glTranslatef(-0.4f, 0.0f, 0.0f);    //向左平移0.4个单位

         glBegin(GL_TRIANGLES);        //注意是逆时针绘制
         glColor4ub(0, 0, 255, 255);   //蓝
         glVertex3f(-0.2f, -0.2f, -1.0f);

         glColor4ub(255, 0, 0, 255);   //红
         glVertex3f(0.2f, -0.2f, -1.0f);

         glColor4ub(0, 255, 0, 255);   //绿
         glVertex3f(0.0f, 0.2f, -1.0f);
         glEnd();
    glPopMatrix();

    glPushMatrix();
         glTranslatef(0.4f, 0.0f, 0.0f);    //向右平移0.4个单位

         glBegin(GL_TRIANGLES);        //注意是逆时针绘制
         glColor4ub(0, 0, 255, 255);   //蓝
         glVertex3f(-0.2f, -0.2f, -1.0f);

         glColor4ub(255, 0, 0, 255);   //红
         glVertex3f(0.2f, -0.2f, -1.0f);

         glColor4ub(0, 255, 0, 255);   //绿
         glVertex3f(0.0f, 0.2f, -1.0f);
         glEnd();
    glPopMatrix();

(2) Effect

5. Attention

Since matrix multiplication does not have the nature of the commutative law, the effects of two different operations on a matrix, which are first rotated and then translated, and first translated and then rotated, are different. (Think about the operation of a model in the unity scene).

Guess you like

Origin blog.csdn.net/weixin_39766005/article/details/128892798