Michelle.J 2024-04-10 14:37 采纳率: 0%
浏览 21

OpenGL中如何让摄像机绕着屏幕中心旋转?

如题,目前我用欧拉角做旋转是以原点为中心而不是以屏幕中心点为中心。而且平移摄像机的话旋转也会出问题。

  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-10 14:37
    关注

    引自免费微信小程序:皆我百晓生

    在OpenGL中,为了让摄像机绕着屏幕中心旋转,你需要明确地定义摄像机的位置坐标,并将其绑定到显存中的数据结构上。这个过程通常被称为“摄像机绑定”。

    以下是一个基本的实现步骤:

    1. 创建一个二维数组,表示摄像机的所有观察点。每个观察点是一个GL/glMatrix4f对象,其中包含矩阵参数。

    2. 设置摄像机的第一个观察点为屏幕中心(0, 0)。

    3. 在循环中,获取当前帧的时间戳和从屏幕左上角(向下)看去的角度。这可以通过glLookAt()函数完成。

    4. 将当前视角相对于屏幕视角进行变换,同时将新的视角存储在摄像机的位置变量中。

    5. 使用glRotatef()函数对摄像机进行旋转。

    6. 重复上述步骤,直到摄像机位置不再改变。

    下面是一个简单的C++代码示例,展示了如何实现上述功能:

    #include <GL/glut.h>
    
    // 实现摄像机绑定
    void Camera绑定(const float* viewPos, const float* camPos) {
        // 创建一个二维数组来存储摄像机所有观察点
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        
        // 创建一个新的`GL/glMatrix4f`对象来表示摄像机的所有观察点
        GLdouble rotation[9];
        glLoadMatrixf(GL接种Matrix4f::translate);
    
        // 设置摄像机的第一个观察点为屏幕中心
        GLdouble translation[2] = {0, 0};
        glMultivectorf(rotation, 1, translation, viewPos[0], viewPos[1]);
        glMultivectorf(camPos, 1, translation, camPos[0], camPos[1]);
    
        // 对摄像机进行旋转
        glRotatef(1, 1, 1, -cos(0.0));
    }
    
    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutCreateWindow("Camera Animation");
        
        // 连接多个显示器
        glutSwapBuffers();
        
        while (true) {
            // 获取当前帧的时间戳
            double timestamp = glutGetTime();
            
            // 计算从屏幕左上角看去的角度
            float screenSizeX = 800;
            float screenSizeY = 600;
            float x = screenSizeX / 2.0;
            float y = screenSizeY / 2.0;
            float angle = atan2(y, x);
            
            // 更新摄像机的位置并执行旋转操作
            Camera绑定(screenSizeX * angle, viewBox[0] + x, viewBox[1] + y);
        }
        
        return 0;
    }
    

    注意:以上代码仅作为一个基本示例,实际使用时可能需要根据具体需求对其进行调整。例如,你可能需要处理不同的摄像机角度、视口大小、显示器间距等问题。此外,这个例子中的glEnable()glDisable()函数并没有被包含在main()函数中,因为在大多数现代 OpenGL 环境中,这些函数已经被弃用,你可以使用 glClear()glDepthRange() 函数来替代它们。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月10日

悬赏问题

  • ¥15 Android Navigation: 某XDirections类不能自动生成
  • ¥20 C#上传XML格式数据
  • ¥15 elementui上传结合oss接口断点续传,现在只差停止上传和继续上传,各大精英看下
  • ¥100 单片机hardfaulr
  • ¥20 手机截图相片分辨率降低一半
  • ¥50 求一段sql语句,遇到小难题了,可以50米解决
  • ¥15 速求,对多种商品的购买力优化问题(用遗传算法、枚举法、粒子群算法、模拟退火算法等方法求解)
  • ¥100 速求!商品购买力最优化问题(用遗传算法求解,给出python代码)
  • ¥15 虚拟机检测,可以是封装好的DLL,可付费
  • ¥15 kafka无法正常启动(只启动了一瞬间会然后挂了)