How to calculate the shift parameters of glTransla

2019-06-13 16:16发布

问题:

I am a newbie to opengl and confused about how to caculate the parameters of glTranslatef. Here is my display code

void display()
{


    glPushMatrix();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);   // background

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glScalef(1.f,1.f,1.f);
    glTranslatef(2.f,0.f,0);


    glBegin(GL_QUADS);
    glVertex2f(-1.0f,-1.0f);
    glTexCoord2f(0.0f,1.0f); 

    glVertex2f(1.0f,-1.0f);
    glTexCoord2f(0.0f,0.0f); 

    glVertex2f(1.0f,1.0f);
    glTexCoord2f(1.0f,0.0f); 

    glVertex2f(-1.0f,1.0f);
    glTexCoord2f(1.0f,1.0f); 

    glEnd();  
    //here is my drawing code,ignore it
    runCuda();
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);

    glBindTexture(GL_TEXTURE_2D, textureID);

    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1024, 768,/*window_width, window_height,*/ 
        GL_RGB, GL_UNSIGNED_BYTE, NULL);

    glPopMatrix();
    glFlush();
}

here is my initiate gl code

 bool initGL(int argc, char **argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);
    glutInitWindowSize(window_width, window_height);
    glutCreateWindow("Cuda GL Interop Demo (adapted from NVDIA's simpleGL)");

    glutDisplayFunc(fpsDisplay);

    glewInit();
    if(!glewIsSupported("GL_VERSION_2_0"))
    {
        fprintf(stderr, "ERROR: Support for necessary OpengGL extensions missing.");
        return false;
    }

    glViewport(0, 0, window_width, window_height);  

    glClearColor(0.0, 0.0, 0.0, 1.0);  
    glDisable(GL_DEPTH_TEST);  

    glMatrixMode(GL_MODELVIEW);  
    glLoadIdentity();  

    glMatrixMode(GL_PROJECTION); // Add this line
    glLoadIdentity(); 

    gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f);//, -1.0f, 1.0f);  


    return true;
    }

The problem is that,When nScale = 1.f,we apply gltranslatef(1.f,0,0) to move leftside at the middle of the window, and gltranslatef(2.f,0,0) to move the picture out of window(2.f is the munimum shift value to move picture out of window).But if I change the nScale to 2.f ,we need change to x_shift to 1.5f(gltranslatef(1.5f,0,0))to move the picture of the window ,or change the nScale to 4.f ,we need change to x_shift to 1.25f to move the picture of the window.I am confused about x_shift(or y_shift) in gltranslate function. It looks that we need change the shift value to (1 + 1/nScale^2),is that correct?How to get that equation?I hope someone can help me. here is the original pic:

here is the pic applied to (glScalef(1.f,1.f,1.f),glTranslatef(1.f,0.f,0))

here is the pic applied to (glScalef(1.f,1.f,1.f),glTranslatef(2.f,0.f,0)),which is moved out of window just right

回答1:

Transformations in OpenGL are applied in the reverse order of the order they are specified in. In other words, the last transformation that is specified is applied to the vertices first.

In this specific case, the way the code is written (with different values for illustration):

glScalef(1.5f, 1.5f, 1.5f);
glTranslatef(2.0f, 0.0f, 0.0f);

This first translates all your vertices by 2.0 in the x-direction. And then scales the whole thing by 1.5. Since the original center of the image was translated to (2.0, 0.0, 0.0) in the first step, the center of the image after scaling by 1.5 is now at (3.0, 0.0, 0.0).

To apply the translation to the already scaled image, the order of these calls needs to be reversed:

glTranslatef(2.0f, 0.0f, 0.0f);
glScalef(1.5f, 1.5f, 1.5f);

Now the scaling will be applied to your vertices first, and then they will be translated. The center of the image after these two transformations will be at (2.0, 0.0, 0.0).



回答2:

Oh nice old OpenGL code question.

In OpenGL 1 & 2 the glTranslate, glRotate and glScale functions apply to the current matrix. In nominal circumstances the modelview matrix (GL_MODELVIEW) is selected. So, in your code you continuously alter the model matrix. After you alter the scale, your calls to glTranslate will naturally scale appropriately.

The way to individually render multiple objects would be to use glPushMatrix and glPopMatrix.

A traditional render function would look something like:

glLoadIdentity();

// set view matrix
glTranslate(<-camera position>);
glRotate(<-camera orientation>);


// first object
glPushMatrix();
glTranslate(<object position>);
glRotate(<object orientation>);
glScale(<object scale>);

// draw object

glPopMatrix();

// second object
glPushMatrix();
glTranslate(<object position>);
glRotate(<object orientation>);
glScale(<object scale>);

// draw object

glPopMatrix();

If you had the object transformation matrix already computed, you would just glMultMatrix with it.

But that is history, since now with OpenGL 3 & 4 you provide the matrices as uniforms to a shader and the functions glTranslate, glRotate and glScale are of the past.