現在、glOrtho を使用して、レンダリング中の 2D グラフをズームおよびパンしています。
ビューポートを標準の幅と高さに設定しました。次に、錐台が画面座標を世界座標と一致させるように glOrtho を設定します。
glViewport(0, 0, window_width,window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width,window_height,0 , 100, -100);
マウスのコールバックでズーム機能を実行すると、錐台のエッジにズーム係数が乗算されます....
glOrtho( 0 * zoomOut,
window_width * zoomOut,
window_height * zoomOut,
0 * zoomOut,
100, -100);
私の質問は....マウスの位置を中心にズームするにはどうすればよいですか?
私はこれを試しました...(ここで、mouseStoreXとmouseStoreYは最初のクリックで保存された位置です)
glOrtho( (0 -mouseStoreX )* zoomOut + mouseStoreX,
(window_width - mouseStoreX) * zoomOut + mouseStoreX,
(window_height - mouseStoreY) * zoomOut + mouseStoreY,
(0 - mouseStoreY) * zoomOut + mouseStoreY,
100, -100);
動作しているように見えますが、新しいクリックをすると錐台が飛び跳ねます。マウス位置の保存を行うときに、ズームアウト要因を考慮していないところがあると思います。
編集:これは私がまだ苦労している私の最新のコードです...
void ZoomOrtho(){ //ON MOUSE CLICK.....
if (zooming == false){
keyStore.LMx = keyStore.Mx; //store mouse pos for next comparison
keyStore.LMy = keyStore.My;
//get mouse pos
mouseStoreX = keyStore.Mx;//mouse pos at this moment
mouseStoreY = keyStore.My;
//get current projection matrices
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
//flip Y for opengl reasons
winY = (float)viewport[3] - winY;
//get world mouse coordinate
gluUnProject( mouseStoreX, mouseStoreY , 0.0, modelview, projection, viewport, &posX_,&posY_, &posZ_);
// calc difference between mouse world pos and centre of 'camera'
dx = posX_ - FS.centerX;
dy = posY_ - FS.centerY;
}
//ON DRAG......
zooming = true;
//do mouse movement detection and increment zoomOut
//#################################################
int xDiff = keyStore.Mx - keyStore.LMx; //mouse drag difference in screen space just for incrementing zoom
int yDiff = keyStore.My - keyStore.LMy; //
if (xDiff > 0 && (zoomFactor >= 0.5 ) ) {
zoomFactor -= zoomInc;
if (zoomFactor < 0.5 ) {zoomFactor = 0.5;}
}
else if (xDiff < 0 && (zoomFactor <= 2.0 )) {
zoomFactor += zoomInc;
if (zoomFactor > 2.0){zoomFactor = 2.0;}
}
//#################################################
//fill structure with clipping plane values. zooms ortho projection and keeps mouse pos anchored.
FS.left = ((FS.centerX - dx - (window_width/2.0))*zoomFactor) +dx;
FS.right = ((FS.centerX -dx + (window_width/2.0))*zoomFactor)+dx ;
FS.bottom = ((FS.centerY -dy + (window_width/2.0))*zoomFactor)+dy;
FS.top = ((FS.centerY -dy - (window_width/2.0))*zoomFactor) +dy;
// store last mouse pos for next comparison.
keyStore.LMx = keyStore.Mx;
keyStore.LMy = keyStore.My;
}
void zoomRelease(){
cout << " releasing" << std::endl;
//set zoom to false so we know we are not draggin mouse anymore.
zooming = false;
keyStore.LMx = 0;
keyStore.LMy = 0;
// recenter by taking midpoint between new left and right clipping planes so dx has a reference point
FS.centreX = (FS.right-FS.left)/2.0;
}
void DrawGui(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(FS.left, FS.right,FS.bottom, FS.top, 1, -1);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
//do drawing
}