美文网首页
OpenGL 正方形键位控制

OpenGL 正方形键位控制

作者: 爱编程真是太好了啦 | 来源:发表于2020-07-07 16:22 被阅读0次

    1.先看一下效果

    QQ20200707-142956.gif

    2.流程图

    键盘控制正方形移动.png

    3.开始绘制

    1.OpenGL环境搭建:OpenGL环境搭建
    2.准备工具类

    • 着色管理器
    GLShaderManager shaderManager;
    
    • 批次类
    GLBatch triangleBatch;
    
    • 定义顶点到原心距离,即 正方形边长 = blockSize * 2
    GLfloat blockSize = 0.1f;
    
    • 修改顶点数组
    GLfloat vVerts[] = {
        -blockSize, -blockSize, 0.0f,
        blockSize, -blockSize, 0.0f,
        blockSize, blockSize, 0.0f,
        -blockSize, blockSize, 0.0f,
    };
    
    • 修改setupRC函数中图元的连接方式
    //将 GL_TRIANGLES 修改为 GL_TRIANGLE_FAN ,4个顶点
        triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    

    3.键位控制效果
    主要是指正方形根据选择键盘的上下左右键移动
    该效果的实现有两种方式

    打个比方,有100件需要染同一种颜色的衣服,你可以选择一件一件的染色,也可以选择同时将100件放入染缸,一起染色,
    -坐标更新方式
    其中一件一件染色指代的就是坐标更新方式,适用于顶点较少的图形,
    顶点根据相对顶点逐个更新顶点坐标,在SpecialKeys函数中完成键位移动时坐标的更新,并手动调用渲染。


    自定义函数流程图.png

    具体代码如下

    void SpecialKeys(int key, int x, int y){
        
        GLfloat stepSize = 0.025f;
        
        GLfloat blockX = vVerts[0];
        GLfloat blockY = vVerts[10];
        
        printf("v[0] = %f\n",blockX);
        printf("v[10] = %f\n",blockY);
        
        
        if (key == GLUT_KEY_UP) {
            
            blockY += stepSize;
        }
        
        if (key == GLUT_KEY_DOWN) {
            
            blockY -= stepSize;
        }
        
        if (key == GLUT_KEY_LEFT) {
            blockX -= stepSize;
        }
        
        if (key == GLUT_KEY_RIGHT) {
            blockX += stepSize;
        }
    
        //触碰到边界(4个边界)的处理
        
        //当正方形移动超过最左边的时候
        if (blockX < -1.0f) {
            blockX = -1.0f;
        }
        
        //当正方形移动到最右边时
        //1.0 - blockSize * 2 = 总边长 - 正方形的边长 = 最左边点的位置
        if (blockX > (1.0 - blockSize * 2)) {
            blockX = 1.0f - blockSize * 2;
        }
        
        //当正方形移动到最下面时
        //-1.0 - blockSize * 2 = Y(负轴边界) - 正方形边长 = 最下面点的位置
        if (blockY < -1.0f + blockSize * 2 ) {
            
            blockY = -1.0f + blockSize * 2;
        }
        
        //当正方形移动到最上面时
        if (blockY > 1.0f) {
            
            blockY = 1.0f;
            
        }
    
        printf("blockX = %f\n",blockX);
        printf("blockY = %f\n",blockY);
        
        // Recalculate vertex positions
        vVerts[0] = blockX;
        vVerts[1] = blockY - blockSize*2;
        printf("(%f,%f)\n",vVerts[0],vVerts[1]);
        
        vVerts[3] = blockX + blockSize*2;
        vVerts[4] = blockY - blockSize*2;
        printf("(%f,%f)\n",vVerts[3],vVerts[4]);
        
        vVerts[6] = blockX + blockSize*2;
        vVerts[7] = blockY;
        printf("(%f,%f)\n",vVerts[6],vVerts[7]);
        
        vVerts[9] = blockX;
        vVerts[10] = blockY;
        printf("(%f,%f)\n",vVerts[9],vVerts[10]);
        
        triangleBatch.CopyVertexData3f(vVerts);
        
        glutPostRedisplay();
    }
    

    -矩阵方式

    image.png

    同时放入染色指代的就是矩阵方式,当图形顶点非常多的,再用坐标更新就不合适了,需要使用矩阵来同时更新。
    -定义步长及两个全局变量(相对于x轴和y轴的平移距离)

    //记录移动图形时,在x轴上平移的距离
    GLfloat xPos = 0.0f;
    //记录移动图形时,在y轴上平移的距离
    GLfloat yPos = 0.0f;
    
    GLfloat stepSize = 0.025f;
    

    -具体代码

    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;
        }
        
        //碰撞检测 xPos是平移距离,即移动量
        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;
        }
        
        glutPostRedisplay();
        
    }
    

    -RenderScene 函数

    //开始渲染
    void RenderScene(void)
    
    {
        //1.清除一个或者一组特定的缓存区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        
        //1.设置颜色RGBA
        GLfloat vRed[] = {1.0f, 0.5f, 0.0f, 1.0f};
        
        
        //定义矩阵
        M3DMatrix44f mTransformMatrix;
        
        //平移矩阵
        m3dTranslationMatrix44(mTransformMatrix, xPos, yPos, 0.0f);
        
        //当单元着色器不够用时,使用平面着色器
        //参数1:存储着色器类型
        //参数2:使用什么矩阵变换
        //参数3:颜色
        shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix, vRed);
        
        //提交着色器
        triangleBatch.Draw();
        glutSwapBuffers();
    }
    

    4.run

    相关文章

      网友评论

          本文标题:OpenGL 正方形键位控制

          本文链接:https://www.haomeiwen.com/subject/xsnaqktx.html