OpenGL 控制你的正方形

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

之前的 OpenGL 环境搭建 - MacOS 文章中,我们完成了OpenGL的环境搭建和测试用的绘制一个正方形。今天我们接着来做一个能够随我们控制移动的多边形。 好的,话不多说,直接开始今天的内容吧:

方法一: 我们通过注册键盘按键的回调,来计算出四个顶点的移动,然后来绘制出移动后的正方形

1 main函数中注册键盘回调

    // 注册键盘函数
    glutSpecialFunc(KeyboardCallback);
复制代码

2 处理按键回调 (计算四个顶点移动后的位置,做边界控制,)

// 移动距离
GLfloat moveDistance = 0.13f;
// 键盘按键回调
void KeyboardCallback( int key, int x, int y ) {
    
    // 1、计算各个顶点坐标
    GLfloat blockX_A = coordinatePoints[0];
    GLfloat blockY_A = coordinatePoints[1];
    GLfloat blockX_B = coordinatePoints[3];
    GLfloat blockY_B = coordinatePoints[4];
    GLfloat blockX_C = coordinatePoints[6];
    GLfloat blockY_C = coordinatePoints[7];
    GLfloat blockX_D = coordinatePoints[9];
    GLfloat blockY_D = coordinatePoints[10];
    
    // 计算移动后的数据
    if (key == GLUT_KEY_UP) {
        
        if (blockY_C >= 1.f) {// 边界控制
            
            blockY_A = 1.f-sideLength*2;
            blockY_B = 1.f-sideLength*2;
            blockY_C = 1.f;
            blockY_D = 1.f;
        }else {
            
            blockY_A += moveDistance;
            blockY_B += moveDistance;
            blockY_C += moveDistance;
            blockY_D += moveDistance;
        }
    }
    if (key == GLUT_KEY_DOWN) {
        if (blockY_A <= -1.f) {// 边界控制
            
            blockY_A = -1.f;
            blockY_B = -1.f+sideLength*2;
            blockY_C = -1.f+sideLength*2;
            blockY_D = -1.f;
        }else {
            
            blockY_A -= moveDistance;
            blockY_B -= moveDistance;
            blockY_C -= moveDistance;
            blockY_D -= moveDistance;
        }
    }
    if (key == GLUT_KEY_LEFT) {
        if (blockX_A <= -1.f) {// 边界控制
            
            blockX_A = -1.f;
            blockX_B = -1.f+sideLength*2;
            blockX_C = -1.f+sideLength*2;
            blockX_D = -1.f;
        }else {
            
            blockX_A -= moveDistance;
            blockX_B -= moveDistance;
            blockX_C -= moveDistance;
            blockX_D -= moveDistance;
        }
    }
    if (key == GLUT_KEY_RIGHT) {
        if (blockX_C >= 1.f) {// 边界控制
            
            blockX_A = 1.f-sideLength*2;
            blockX_B = 1.f;
            blockX_C = 1.f;
            blockX_D = 1.f-sideLength*2;
        }else {
         
            blockX_A += moveDistance;
            blockX_B += moveDistance;
            blockX_C += moveDistance;
            blockX_D += moveDistance;
        }
    }
    
    coordinatePoints[0] = blockX_A;
    coordinatePoints[1] = blockY_A;
    coordinatePoints[3] = blockX_B;
    coordinatePoints[4] = blockY_B;
    coordinatePoints[6] = blockX_C;
    coordinatePoints[7] = blockY_C;
    coordinatePoints[9] = blockX_D;
    coordinatePoints[10] = blockY_D;
    
    triangleBatch.CopyVertexData3f(coordinatePoints);
    glutPostRedisplay();
}
复制代码

方法二:使用 平面着色器绘制

1 定义x坐标和y坐标移动的距离

GLfloat xMove = 0.f;//x坐标移动距离
GLfloat yMove = 0.f;//y坐标移动距离
复制代码

2 键盘按键回调的函数中处理 x、y坐标移动的距离;并提交渲染

// 键盘按键回调
void KeyboardCallback( int key, int x, int y ) {
    
    // 计算移动后的数据
    if (key == GLUT_KEY_UP) {
        
        yMove += moveDistance;
    }
    if (key == GLUT_KEY_DOWN) {
        yMove -= moveDistance;
    }
    if (key == GLUT_KEY_LEFT) {
        xMove -= moveDistance;
    }
    if (key == GLUT_KEY_RIGHT) {
        xMove += moveDistance;
    }
    
    // 碰撞检测
    if (xMove < -1.f+sideLength) {
        xMove = -1.f+sideLength;
    }
    if (xMove > 1.f-sideLength) {
        xMove = 1.f-sideLength;
    }
    
    if (yMove<-1.f+sideLength) {
        yMove = -1.f+sideLength;
    }
    if (yMove>1.f-sideLength) {
        yMove = 1.f-sideLength;
    }
    //提交渲染 之后会执行 RenderScene 方法
    glutPostRedisplay();
    
}
复制代码

3 开始渲染

//开始渲染
void RenderScene(void) {
    
    //清除一个或一组特定的缓冲区
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

    GLfloat red[] = {1.0f,0.0f,0.0f,0.0f};
    
    // 矩阵
    M3DMatrix44f mTransformMatrix;
    // 平移矩阵,结果存储在 mTransformMatrix 中;
    m3dTranslationMatrix44(mTransformMatrix, xMove, yMove, 0.f);
    
    //平面着色器(固定着色器)
    shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix,red);
    
    //提交着色器 绘制
    triangleBatch.Draw();
    
    //将在后台缓冲区进行渲染,然后在结束时交换到前台
    glutSwapBuffers();
}
复制代码

总结一下方法二,我们不用去计算每一个坐标点的位置:

通过定义 M3DMatrix44f

使用 m3dTranslationMatrix44 方法来讲移动后的结果保存到 M3DMatrix44f

接着提交渲染绘制就完成了

效果如下:

2.gif

猜你喜欢

转载自juejin.im/post/7102728323712679967