falkb
falkb

Reputation: 1349

How to get the whole scene rotate around itself? (my code has a little bug which just lets the objects rotate around themselves)

What must be changed to let me see the impression of flying around the whole fixed scene? My current code just lets me look from a fixed viewpoint at objects each one rotating around itself. Enabling glLoadIdentity() just stops their rotation. Note that 3dWidget::paintGL() is permanently called by a timer every 20ms.

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);
}

EDIT: It seems it's important to know that 2 cubes are created with the following 3D position coordinates (m_x, m_y, m_z):

void 3dWidget::createScene()
{
    Cube* pCube = new Cube;
    pCube->create(0.5 /*size*/, -0.5 /*m_x*/, -0.5 /*m_y*/, -0.5 /*m_z*/);
    pCube = new Cube;
    pCube->create(0.5 /*size*/, +0.5 /*m_x*/, +0.5 /*m_y*/, +0.5 /*m_z*/);
}

Upvotes: 0

Views: 151

Answers (2)

falkb
falkb

Reputation: 1349

Now I've found the reason by myself. It works as soon as I change method paintGL() to

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();
    }
}

I don't get it exactly why, but it obviously appeared that some transformations had compensated in a way that the objects just rotate around itself. Thanks for your help anyway.

I think it's always better to let the scene rotate than to move by gluLookAt (beside the issue that finding the right formula for the angle of view is more difficult).

Upvotes: 0

Marcelo Cantos
Marcelo Cantos

Reputation: 185852

Use gluLookAt to position the camera. You apply it to the modelview matrix before any object transforms.

Obviously, you'll have to figure out a path for the camera to follow. That's up you and how you want the "flight" to proceed.

EDIT: Just to be clear, there's no camera concept, as such, in OpenGL. gluLookAt is just another transform that (when applied to the modelview matrix) has the effect of placing a camera at the prescribed location.

If you really are just trying to rotate the world, your code seems to perform the transforms in a reasonable order. I can't see why your objects rotate around themselves rather than as a group. It might help to present a SSCCE using glut.

Upvotes: 1

Related Questions