美文网首页
三、OpenGL案例-正方形的移动

三、OpenGL案例-正方形的移动

作者: 顺7zi燃 | 来源:发表于2020-07-06 17:48 被阅读0次

    案例:用OpenGL实现 通过上下左右键移动屏幕中的小方块
    1.OpenGL 环境配置
    2.执行流程

    image.png

    2.1


    函数思维导图.png

    3.案例代码
    3.1引入头文件

    //着色管理器类
    #include "GLShaderManager.h"
    //包含大部分GLTool中类似C语言的独立函数
    #include "GLTools.h"
    //GLUT
    #include <GLUT/GLUT.h>
    

    3.2准备工作

    // 定义一个,着色管理器
    GLShaderManager shaderManager;
    // 简单的批次容器,是GLTools的一个简单的容器类
    GLBatch triangleBatch;
    
    // blockSize 边长
    GLfloat blockSize = 0.1f;
    // 正方形的4个坐标
    GLfloat vVerts[] = {
        -blockSize, blockSize, 0.0f, // 左上
        blockSize, blockSize, 0.0f,  // 右上
        blockSize, -blockSize, 0.0f,  // 右下
        -blockSize, -blockSize, 0.0f  // 左下
    };
    // x 方向的位移量
    GLfloat xPos = 0.0f;
    // y 方向的位移量
    GLfloat yPos = 0.0f;
    

    3.3main函数

    int main(int argc, char *argv[])
    {
        // 设置当前工作目录
        gltSetWorkingDirectory(argv[0]);
        // 初始化 GLUT库
        glutInit(&argc, argv);
        
        // 初始化缓冲窗口
        //其中标志GLUT_DOUBLE(双缓冲窗口)、GLUT_RGBA(RGBA颜色模式)、GLUT_DEPTH(深度测试)、GLUT_STENCIL(模板缓冲区)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
        // GLUT窗口大小
        glutInitWindowSize(500, 500);
        // GLUT 标题
        glutCreateWindow("Triangle");
        // GLUT 内部运行一个本地消息循环,拦截适当的消息。然后调用我们不同时间注册的回调函数
        // 注册窗口改变大小的回调函数
        glutReshapeFunc(changeSize);
        // 注册OpenGL渲染的回调函数
        glutDisplayFunc(RenderScene);
        // 注册特殊键位响应函数。(当用户使用特殊键位则会调用该函数)
        glutSpecialFunc(SpecialKeys);
        
        // 初始化一个 GLEW 库,确保 Opengl API 对程序完全可用
        GLenum status = glewInit();
        if (GLEW_OK != status) {
            printf("GLEW Error:%s\n", glewGetErrorString(status));
            return 1;
        }
        
        // 设置数据
        setupRc();
        //类似于iOS runloop 运行循环
        glutMainLoop();
        return 0;
    }
    

    3.4setupRC函数

    /*
     触发条件:
     1.手动 main 函数触发
     
     处理业务:
     1.设置窗口背景颜色
     2.初始化存储着色器 shaderManager
     3.设置图形顶点数据
     4.利用GLBatch 三角形批次类,将数据传递到着色器
     */
    void setupRc()
    {
        //设置清屏颜色
        glClearColor(0.9f, 0.0f, 0.0f, 1);
        //初始化着色器
        shaderManager.InitializeStockShaders();
        //指定顶点
        triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
        triangleBatch.CopyVertexData3f(vVerts);
        triangleBatch.End();
    }
    

    3.5changeSize函数

    // 在窗口大小改变时,接收新的宽&高
    /*
     触发条件:
     1.新建窗口
     2.窗口尺寸发生调整
     
     处理业务 :
     1设置OpenGL 视口
     2设置OpenGL 投影方式
     */
    void changeSize(int w, int h)
    {
        glViewport(0, 0, w, h);
    }
    

    3.6RenderScene函数

    /*
     触发条件:
     1.系统自动触发
     2.开发者手动调用函数触发。
     
     处理业务:
     1.清理缓存区(颜色,深度,模板缓存区等)
     2.使用存储着色器
     3.绘制图形
     */
    void RenderScene(void)
    {
        // 清除一个或者一组特定的缓存区
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        // 设置颜色RGBA
        GLfloat VRed[] = {0.0f, 0.7f, 0.0f, 0.0f};
        // 自定义矩阵
        M3DMatrix44f mTransformMatrix, mRotationMartix;
        // 平移
        m3dTranslationMatrix44(mTransformMatrix, xPos, yPos, 0.0f);
        
        //将矩阵结果 提交给固定着色器(平面着色器)中绘制
        // 参数1 :存储着色器类型
        // 参数2 :使用什么矩阵变换
        // 参数3 :颜色
        shaderManager.UseStockShader(GLT_SHADER_FLAT, mTransformMatrix, VRed);
        // 提交着色器
        triangleBatch.Draw();
        // 执行交换缓冲区
        glutSwapBuffers();
    }
    

    3.7SpecialKeys函数

    // 特殊键位
    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;
        
        printf("xPos = %lf,  yPos = %lf\n", xPos, yPos);
        // 碰撞检测
        if (xPos < (-1.0 + blockSize)) xPos = -1.0 + blockSize;
        
        if (xPos > 1.0 - blockSize) xPos = 1.0 - blockSize;
        
        if (yPos < (-1.0 + blockSize)) yPos = -1.0 + blockSize;
        
        if (yPos > (1.0 - blockSize)) yPos = 1.0 - blockSize;
        
        printf("碰撞检测后:xPos = %lf,  yPos = %lf\n", xPos, yPos);
    
        glutPostRedisplay();
    }
    

    相关文章

      网友评论

          本文标题:三、OpenGL案例-正方形的移动

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