OpenGL 实现图形旋转移动

准备工作:

需要用到资源 CLTools, glew, libGLTools.a。获取这三个资源可以查看我的上一篇文章。链接[https://www.jianshu.com/p/4026a8ef0f32�].

具体实现步骤:

  1. 程序的入口是main()函数,我们在main函数里先要初始化GLUT库,设置双缓冲窗口和窗口的大小,并且要注册2个回调函数ChangeSize(), RenderScene(), 注册特殊函数SpecialKeys(),来保证我们的图形能旋转并且移动(我们以正方形为例)。glutMainLoop() 函数是循环调用,相当于RunLoop。
int main(int argc,char* argv[]) {
    //设置当前工作目录,针对MAC OS X
    gltSetWorkingDirectory(argv[0]);
    //初始化GLUT库
    glutInit(&argc, argv);
    /*初始化双缓冲窗口,其中标志GLUT_DOUBLE、GLUT_RGBA、GLUT_DEPTH、GLUT_STENCIL分别指双缓冲窗口、RGBA颜色模式、深度测试、模板缓冲区*/
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
    //GLUT窗口大小,标题窗口
    glutInitWindowSize(500,500);
    glutCreateWindow("Triangle");
    //注册回调函数
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    //注册特殊函数
    glutSpecialFunc(SpecialKeys);
    //驱动程序的初始化中没有出现任何问题。
    GLenum err = glewInit();
    if(GLEW_OK != err) {
        fprintf(stderr,"glew error:%s\n",glewGetErrorString(err));
        return 1;
    }
    //设置我们的渲染环境
    SetupRC();
   //循环调用,相当于RunLoop
    glutMainLoop();
    return 0;
}
  1. 定义全局变量,正方形的边长 blockSize 以及4个顶点坐标,定义中心点坐标(xPos, yPos)为原点进行移动
    image.png
//blockSize 边长
GLfloat blockSize = 0.1f;
//正方形的4个点坐标,a,b,c,d四个顶点,每个顶点有x,y,z轴
GLfloat vVerts[] = {
        -blockSize,-blockSize,0.0f,
        blockSize,-blockSize,0.0f,
        blockSize,blockSize,0.0f,
        -blockSize,blockSize,0.0f
};
//中心点x, y开始的坐标
GLfloat xPos = 0.0f;
GLfloat yPos = 0.0f;
  1. SetupRC()为程序做一次性设置,该方法就只调用一次,设置一些必要条件
void SetupRC() {
    //设置背景颜色
    glClearColor(0.0f,0.0f,1.0f,1.0f);
    //初始化着色管理器
    shaderManager.InitializeStockShaders();
    //修改为GL_TRIANGLE_FAN ,顶点收尾相连,4个顶点(正方形)
    /*
        GL_LINES, GL_LINE_LOOP, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, GL_POLYGON  , 这几个枚举值是设置顶点的连接方式,自己可以每个都试一下。
    */
    triangleBatch.Begin(GL_TRIANGLE_FAN,4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}
  1. changeSize()函数是设置窗口的大小,实时接收新的宽高。
void changeSize(int w,int h) {
    /*
      x,y 参数代表窗口中视图的左下角坐标,而宽度、高度是像素为表示,通常x,y 都是为0
     */
    glViewport(0, 0, w, h);
}
  1. RenderScene()是设置显示在屏幕上的函数,用到了4x4的矩阵M3DMatrix44f方法来进行设置
void RenderScene() {
    //1.清除一个或者一组特定的缓存区
    /*
     缓冲区是一块存在图像信息的储存空间,红色、绿色、蓝色和alpha分量通常一起分量通常一起作为颜色缓存区或像素缓存区引用。
     OpenGL 中不止一种缓冲区(颜色缓存区、深度缓存区和模板缓存区)
      清除缓存区对数值进行预置
     参数:指定将要清除的缓存的
     GL_COLOR_BUFFER_BIT :指示当前激活的用来进行颜色写入缓冲区
     GL_DEPTH_BUFFER_BIT :指示深度缓存区
     GL_STENCIL_BUFFER_BIT:指示模板缓冲区
     */    
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    //2.设置一组浮点数来表示红色
    GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};
    //定义一个4x4的矩阵
    M3DMatrix44f mFinalTransform,mTransfromMatrix,mRotationMartix;
    //调用平移方法
    m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.0f);
    //每次平移时,旋转5度
    static float yRot = 0.0f;
    yRot += 5.0f;
   //调用旋转方法
    m3dRotationMatrix44(mRotationMartix, m3dDegToRad(yRot), 0.0f, 0.0f, 1.0f);
    //将旋转和移动的矩阵结果 合并到mFinalTransform (矩阵相乘)
    m3dMatrixMultiply44(mFinalTransform, mTransfromMatrix, mRotationMartix);
    //将矩阵结果 提交给固定着色器(平面着色器)中绘制
    shaderManager.UseStockShader(GLT_SHADER_FLAT,mFinalTransform,vRed);
    //提交着色器
    triangleBatch.Draw();
    //执行交换缓存区
    glutSwapBuffers();
}
  1. 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;
    }
    //重新绘制
    glutPostRedisplay();
}
  1. 至此已经完成了用OpenGL实现了一个正方形移动并且旋转的小Demo。


    QQ20200704-155519-HD.gif

你可能感兴趣的:(OpenGL 实现图形旋转移动)