OpenGL绘制正方形并平移旋转

2020-07-05  本文已影响0人  AndyGF

本案例将使用 OpenGL 在 Mac 环境在窗口中心绘制一个正方形, 监听键盘的上, 下, 左, 右按键, 实现每次平移的同时旋转5度, 由于工具版本比较低, Xcode 我版本高, 第一次启动时会有个小bug, 但是并不影响后边的探索, 图形会先在左下角, 拖动一下窗口, 就到屏幕中间了. 主要包括两部分, 绘制流程图和主要代码, 环境请自己搭建. 如有需要可联系本人提供对应的工具.

一.绘制流程图

二.代码

如有不懂的代码, 请参考三角形绘制中注释

1. 头文件

#include "GLTools.h"
#include <GLUT/GLUT.h>

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 / y 方向
GLfloat xPos = 0.0f;
GLfloat yPos = 0.0f;

// 正方形旋转角度累计
GLfloat yRot = 0.0f;

3. main 函数

int main(int argc,char *argv[])
{
    gltSetWorkingDirectory(argv[0]);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Triangle")
    glutReshapeFunc(changeSize);
    glutDisplayFunc(RenderScene);

    //注册特殊键位监听函数
   glutSpecialFunc(SpecialKeys);
    
    GLenum status = glewInit();
    if (GLEW_OK != status) {
        printf("GLEW Error:%s\n",glewGetErrorString(status));
        return 1;
    }
   
    setupRC();
    glutMainLoop();
    return  0;
}

4. SetupRC 函数

void setupRC()
{
    glClearColor(0.8f, 0.9f, 0.9f, 1.0f);
    shaderManager.InitializeStockShaders();
    
    triangleBatch.Begin(GL_TRIANGLE_FAN, 4);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}

5. changeSize 函数

  • 初始化时调用一次
  • 当窗口大小改变时, 会调用此函数, 比如拖动改变窗口大小.
/*
 在窗口大小改变时,接收新的宽度&高度。
 */
void changeSize(int w,int h)
{
    glViewport(0, 0, w, h);  
}

6. RenderSence 函数

  • 初始化时调用一次
  • 重新绘制时, 会调用此函数
void RenderScene(void)
{

    //1.清除一个或者一组特定的缓存区
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    
    GLfloat vRed[] = {1.0f,0.0f,0.0f,0.0f};

    // 定义矩阵
    M3DMatrix44f mFinalTransform, mTransfromMatrix, mRotationMartix;
    
    //平移
    m3dTranslationMatrix44(mTransfromMatrix, xPos, yPos, 0.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();  
}

7.上下左右 键位监听

void SpecialKeys(int key, int x, int y){
    
    // 旋转
    yRot += 5.0f;

    // 平移步长
    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;
    }
    
    // 手动调用 RenderSence 函数进行重绘
    glutPostRedisplay();
}
上一篇 下一篇

猜你喜欢

热点阅读