OpenGLでズームを実装する方法
OpenGLでズームを実装する方法について。
最初、カメラの中心と距離をいじってやろうと思ってたんだけど、どうも上手くいかなかったから、ちょっと調べたら出てきたました。
元のネタはここの8.040、How do I implement a zoom operation?
https://www.opengl.org/archives/resources/faq/technical/viewing.htm
最も手っ取り早い方法としてModelView行列の対角要素をN倍する方法があるけど、それはスケールが大きく/小さくなりすぎると、Projection行列のNearかFarの影響で描画したいものが正確に表示されないという問題がある。そこで、ModelView行列ではなく、Projection行列を弄ってやればハッピーじゃないかという話です。
例えば、glFrustum、ここではもう少しモダンなOpenGLということでglm::frustumですが、それを使ってズームを実装すると以下のようになります。
glm::frustum(left / scale, right / scale, bottom / scale, top / scale, z_near, z_far);
ただ、これだけだと常に画面中心にしかズームができないので、さらにx,y座標のどこにズームするかを指定できるように以下のように変更してやります。
glm::frustum((left + center_x) / scale, (right + center_x) / scale, (bottom + center_y) / scale, (top + center_y) / scale, z_near, z_far);
ただ、このコード、正確に動くかは検証していません。
なにせ、私の場合near平面のサイズが既知の条件で扱っているので、以下のようになっているかです。
glm::frustum( -0.5f * (this->WindowWidth + this->Center.x) / this->Scale, 0.5f * (this->WindowWidth - this->Center.x) / this->Scale, -0.5f * (this->WindowHeight + this->Center.y) / this->Scale, 0.5f * (this->WindowHeight - this->Center.y) / this->Scale, z_near, z_far );
微妙にthisとかチラチラしてますが基本的な考え方は同じです。