C++ 如何使整个场景围绕自身旋转?(我的代码有一个小错误,它只允许对象围绕自己旋转)

C++ 如何使整个场景围绕自身旋转?(我的代码有一个小错误,它只允许对象围绕自己旋转),c++,opengl,C++,Opengl,为了让我看到在整个固定场景中飞行的印象,必须改变什么?我当前的代码只允许我从固定的视点观察每个围绕自身旋转的对象。启用glLoadIdentity()只会停止它们的旋转。请注意,3dWidget::paintGL()由计时器每隔20毫秒永久调用一次 void 3dWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glTranslatef(0.5f, 0.5f, 0.5f); g

为了让我看到在整个固定场景中飞行的印象,必须改变什么?我当前的代码只允许我从固定的视点观察每个围绕自身旋转的对象。启用glLoadIdentity()只会停止它们的旋转。请注意,3dWidget::paintGL()由计时器每隔20毫秒永久调用一次

void 3dWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glTranslatef(0.5f, 0.5f, 0.5f);
    glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
    glTranslatef(-0.5f, -0.5f, -0.5f);

    glPushMatrix();
    //glLoadIdentity();

    for (int i = 0; i < m_cubes.count(); i++) {
        m_cubes[i]->render();
    }

    glPopMatrix();
}

void Cube::render() {
    glTranslatef(m_x, m_y, m_z); // local position of this object
    glCallList(m_cubeId); // render code is in createRenderCode()
    glTranslatef(-m_x, -m_y, -m_z);
}

void Cube::createRenderCode(int cubeId) {
    m_cubeId = cubeId;

    glVertexPointer(3, GL_FLOAT, 0, m_pCubePoints);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, m_pCubeColors);

    glNewList(m_cubeId, GL_COMPILE);
    {
        glEnableClientState(GL_COLOR_ARRAY);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, m_numPoints);
        glDisableClientState(GL_COLOR_ARRAY);
    }
    glEndList();
}

void 3dWidget::init(int w, int h)
{
    ...

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    float aspect = w/(float)(h ? h : 1);
    glFrustum(-aspect, aspect, -1, 1, 10, 100);
    glTranslatef(0., 0., -12);

    glMatrixMode(GL_MODELVIEW);
}
用于定位相机。在任何对象变换之前,将其应用于modelview矩阵

很明显,你必须找出一条相机可以跟随的路径。这取决于你和你希望“飞行”如何进行

编辑:为了澄清,OpenGL中没有相机概念。gluLookAt只是另一个变换(应用于modelview矩阵时)具有将摄影机放置在指定位置的效果


如果您真的只是尝试旋转世界,那么您的代码似乎以合理的顺序执行转换。我不明白为什么你的物体是围绕着自己旋转的,而不是作为一个整体。这可能有助于呈现一种使用过剩。

现在我自己找到了原因。只要我将方法
paintGL()
更改为

void 3dWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

#if 0 // not working
    glTranslatef(0.5f, 0.5f, 0.5f);
    glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
    glTranslatef(-0.5f, -0.5f, -0.5f);
#else // this works properly, they rotate horizontally around (0,0,0)
    glRotatef(3.0f, 0.0f, 1.0f, 0.0f);
#endif

    for (int i = 0; i < m_cubes.count(); i++) {
        m_cubes[i]->render();
    }
}
void 3dWidget::paintGL()
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
#如果0//不工作
glTranslatef(0.5f,0.5f,0.5f);
glRotatef(3.0f、1.0f、1.0f、1.0f);
GLTRANSTEF(-0.5f,-0.5f,-0.5f);
#否则//这将正常工作,它们将围绕(0,0,0)水平旋转
glRotatef(3.0f、0.0f、1.0f、0.0f);
#恩迪夫
对于(int i=0;irender();
}
}
我不知道确切的原因,但很明显,一些变换以一种方式补偿了对象只是围绕自身旋转。无论如何,谢谢你的帮助


我认为让场景旋转总比通过gluLookAt移动好(除了找到正确的视角公式更困难的问题之外)。

我的代码尝试使用固定摄影机,只想旋转整个场景以获得苍蝇效果。我听说这比移动相机要好。@falkb:实际上OpenGL中没有相机。gluLookAt如果在转换链中的正确位置使用,它只会在场景中移动。@DatenWalf:感谢您指出可能存在的混淆。我添加了一个澄清段落。请同时阅读我自己的答案,与此答案平行。你不移动相机,你移动相机周围的世界;)@棘轮怪胎:是的,我知道从技术上讲,这是必须做到的。我描述了我在观看时的印象中产生的效果。@falkb:我认为我在OpenGL转换管道上的SO答案对你很有价值:你能在我的代码中认识到为什么立方体会围绕自身旋转,以及我应该做些什么来获得观看围绕其中心旋转的场景的效果?在上面的C++代码中,必须改变什么?你的链接很有趣,但没有解释我如何解决我的问题。旁注:你应该集成一个旋转角度(在paintGL中为this->angle+=3)并应用
glIdentity();glTranslatef(…);glRotatef(角度,…);glTranslatef(…)
。这避免了由于矩阵乘法链不断延长而产生的缓慢舍入误差。它还消除了
gl(Push | Pop)矩阵
。您刚刚更改了场景旋转的点。我假设这两个平移是有意围绕点[0.5 0.5 0.5]旋转场景的。这不是故意的吗?@MarceloCantos:可能不够清楚,但“场景围绕自身旋转”的意思是围绕(0,0,0)。translate-rotate-translate代码是从另一个示例复制的。
void 3dWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

#if 0 // not working
    glTranslatef(0.5f, 0.5f, 0.5f);
    glRotatef(3.0f, 1.0f, 1.0f, 1.0f);
    glTranslatef(-0.5f, -0.5f, -0.5f);
#else // this works properly, they rotate horizontally around (0,0,0)
    glRotatef(3.0f, 0.0f, 1.0f, 0.0f);
#endif

    for (int i = 0; i < m_cubes.count(); i++) {
        m_cubes[i]->render();
    }
}