[OpenGL]案例2-使用键盘方向键控制一个正方形移动

2020/7/18 posted in  音视频 总阅读量

上一篇文章我们已经知道如何在屏幕上绘制一个简单的图形,这次我们给图形加上一点交互,根据键盘方向键进行相应的移动和旋转。效果如下:键盘控制四边形移动旋转

执行流程

流程基本和上一个案例渲染一个三角形差不多,我们主要更改的地方是下面的几个函数

  • glutSpecialFunc(SpecialKeys)是我们这次新用到的API, 这个函数用来注册特殊键位响应,当⽤户使⽤特殊键位则会调⽤该函数。

    GLUT_KEY_UP 上方向键
    GLUT_KEY_DOWN 下方向键
    GLUT_KEY_LEFT 左方向键
    GLUT_KEY_RIGHT 右方向键

  • SpecialKeys收到响应后进行相应的回调处理,对移动旋转偏移量进行计算。

void SpecialKeys(int key, int x, int y){

    GLfloat stepSize = 0.025f;
    
    if (key == GLUT_KEY_UP) {
        
        yPos += stepSize;
    }
    
    if (key == GLUT_KEY_DOWN) {
        yPos -= stepSize;
    }
    
    if (key == GLUT_KEY_LEFT) {
        xPos -= stepSize;
    }
    
    if (key == GLUT_KEY_RIGHT) {
        xPos += stepSize;
    }
    
    //碰撞检测
    if (xPos < (-1.0f + blockSize)) {
        
        xPos = -1.0f + blockSize;
    }
    
    if (xPos > (1.0f - blockSize)) {
        xPos = 1.0f - blockSize;
    }
    
    if (yPos < (-1.0f + blockSize)) {
        yPos = -1.0f + blockSize;
    }
    
    if (yPos > (1.0f - blockSize)) {
        yPos = 1.0f - blockSize;
    }
    
    // 手动触发渲染,调用RenderScene
    glutPostRedisplay();
}
  • 我们在RenderScene里进行平移旋转的操作,如果一个顶点一个顶点的计算平移旋转后的坐标,处理起来会非常复杂,通常的做法是通过矩阵来处理,每个顶点都乘以同一个转换矩阵来进行转换。
void RenderScene(void)
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    
    GLfloat vRed[] = {0.8f,0.8f,0.8f,0.0f};
    
    // M3DMatrix44f 4X4的矩阵类型,本质是一个一维数组
    M3DMatrix44f mFinalTransform,mTransfromMatrix,mRotationMartix;
    
    // void m3dTranslationMatrix44(M3DMatrix44f m, float x, float y, float z)
    // 生成一个平移矩阵,m存放生成后的矩阵,x,y,z表示分别向x,y,z平移的长度
    m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
    
    //每次平移时,旋转5度
    static float yRot = 0.0f;
    yRot += 5.0f;
    
    // void m3dRotationMatrix44(M3DMatrix44f m, float angle, float x, float y, float z);
    // 生成一个旋转矩阵, m存储旋转后的矩阵,angle是旋转度数,使用弧度制,旋转的轴为原点和x,y,z的连线。
    //m3dDegToRad(x) 角度转弧度制
    //m3dRadToDeg(x) 弧度转角度制
    m3dRotationMatrix44(mRotationMartix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
    
    // void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);
    // m 存放 a x b 后的结果, 需要注意先后顺序,矩阵点乘不能交换
    // 将旋转和移动的矩阵结果 合并到mFinalTransform (矩阵相乘)
    m3dMatrixMultiply44(mFinalTransform, mTransfromMatrix, mRotationMartix);
    
    //将矩阵结果 提交给固定着色器(平面着色器)中绘制
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
    triangleBatch.Draw();
    
    //执行交换缓存区
    glutSwapBuffers();
}