简体   繁体   中英

OpenGL translation and rotation in the same time

In my openGL project, I am trying to achieve the following: let the object rotate around its origin(the (0,0,0) point in its own world) and simultaneously translate it. I come up with the follwing structure:

/***
Install shader and upload data to openGL, initialize and stuffs...
***/
// transfomration matrix is a global variable
// note the transformation matrix eventually will be right multiplied
// by the vertex data in the vertex shader
void keyboard(){
// Inside this function I capture the keyboard input.
// if rotation key is captured, set the rotation flag
// if translation or scaling key is captured, modify the matrix like this
   transformation = glm::translate() * transformation;
}
void paintGL(){
// Inside this function I check if the rotation flag is up and modify the 
// model to wolrd transformation matrix. I choose to modify the transform
// matrix here because I can take use of the main loop to let my object
// continuously rotate unless the flag is off.
   if(rotation flag is set)
       transformation = transformation * glm::rotate() * inverse(transformation)
}
int main(){
    glutInit();
    glutDisplayFunc(paintGL);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
}

Now my problem is that when I only rotate or only translate or scale, the program works as expected. But if I translate the object and then press rotate, the object goes back to its initial position and then rotate. Or it vanishes!

I know that order matters, but it seems to me that as long as I applied the inverse matrix, the object should go back to its original world and rotate around the origin and then I can translate it back. Is my problem caused by the calling sequence of keyboard and paintGL? Can someone give me some help?

As suggested by@reprodukto, I found the solution for my problem.

I use another two flags for translation and scaling and handle the situation all together inside the paintGL function. In this way I can apply the textbook order of Translate * Rotate * Scaling transformation.

Thank you all for taking the time to comment and answer my question, I really appreciate it!

you will need to have a function that updates x,y&z values. All you need is to create an array that holds your x,y&z values, then you will need to back it up in a temporary array. Delete the old array and replace it with a new one. Its just like this. Create a new variable called POINT that holds x,y,z values which you are going to use when translating your object.

typedef struct
{
      GLfloat xyz[3];

}POINT;

void update(GLfloat x, GLfloat y, GLfloat z)
{
       POINT *point;
       POINT new_point;
         new_point.xyz[0] = x;
         new_point.xyz[1] = y;
         new_point.xyz[2] = z;
       long my_points;
       if(my_points>0)
         point  = new POINT[my_points+1];
       else{
            POINT *temp = new POINT[my_points+1];
         for(long i=0;i<my_points;i++)
                      temp[i] = point[i];
              delete [] point;
              point = NULL;
           //Ok here you allocate new memory
             point = new POINT[my_points+2];
               for(long i=0;i<my_points;i++)
                    point[i] = temp[i];
                 delete [] temp;
                 temp = NULL;
       }
         point[my_points] = new_point;

}

As I'm sure you've read, developers usually think in terms of model, view, and projection matrices. Just to make things clear, it is better to think of these as:

model_to_world matrix (places your model in the game world)

world_to_camera matrix (locates the camera in your world by moving the entire game world around the camera)

world_to_projection matrix (this takes a frustum shape and squishes it into a cube, which is the cube that opengl uses for rendering, a cube from -1 to +1 in the x, y, and z directions)

Remember that matrices can do translation, scaling, and rotation all together at once, and you can multiply your model, view, and projection matrices once before passing a single matrix into your shader program.

I'm not sure exactly what you are doing but I think a better solution is something like this:

glm::mat4 originTransform; // this will initialize a matrix which represents no translation, scaling, or rotation, which will be useful later.
glm::mat4 localMatrix; // your "model" matrix

localMatrix = glm::translate(originTransform, glm::vec3(2.3f, 0.5f, -1.0f)); // I put in random values to translate by.

// 2nd translation:
localMatrix = glm::translate(localMatrix, glm::vec3(5.3f, 2.5f, -10.0f)); // Note that I'm inputting the localMatrix now and not the originTransform, otherwise everything that was done to this matrix before would be made irrelevant.

localMatrix = glm::rotate(localMatrix, 90.0f, glm::vec3(1.0f, 0.0f, 0.0f)); // a 90 degree rotation on the x axis. Again, note that this is done on the localMatrix and not the originTransform.

For the view and projection matrices, please refer to tutorials on the net.

If you're trying to make something 2D and not 3D, or if this doesn't help you fix your problem, please comment and I will edit my answer to try to help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM