OpenGL Mouse Pick & Move on Screen
This sample shows how to Pick some objects from the screen and move an object on the screen. This style is a bit similar to the 3D content creator, like Maya, 3D Max. You could drag some objects to some certain 3d position.This program use OpenGL as the graphics display API.
The first technology point implemented here is how to pick a object with a mouse position on the screen. Well, it seems very convenient for use to pick some objects with OpenGL. The main idea is like this:
1) Those objects that could be viewed from the current camera will be draw with the pure mask color. Every different objects' will have it’s own unique mask color. After the drawing, the color buffer will be filled with the mask color and the depth buffer will be filled with depth value;
2) Read the color value and depth value from the back buffer given by the mouse position. With the color value, we will figure out which object are there(picked by the mouse). With the depth value, we could calculate the corresponding 3d position in the world space.
To read the color value and depth value from the back buffer:
GLubyte pixel[3]; winX = (float)x; winY = (float)viewport[3] – (float)y; glReadBuffer( GL_BACK ); //read color glReadPixels(x, int(winY),1,1,GL_RGB,GL_UNSIGNED_BYTE,(void *)pixel); glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ ); To get the 3d position with mouse: gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
After you find out which object to move and where it will be move to, now you could apply those movement to the selected objects by calculating the delta movement between two move times. The code is like this:
float3 detlalpos = mCurrentPickPos – mPreviousPickPos; object.mPos += delta_pos; mPreviousPickPos = mCurrentPickPos;
This is for the picked object. But If you move some point in the world space, you could even set the point’s position directly when the point’s world transform matrix is identity, just like following:
somePoint.mPos = mCurrentPickPos;
In this sample, you will something that could be improved. When you drag the mouse with move arrow, you will notice that some certain distance between the mouse cursor and the move arrow will increase as you move a long distance along the screen. But this never happen in the Maya, 3D Max. This could be improved if you make the move arrow stick to the mouse cursor.
The full source code could be download from here.