射影行列を変更せずにこれを行うことができると思います。結局のところ、考えてみれば、実際には投影を変更したくありません。投影されたジオメトリのどの部分がレンダリング サーフェスにマップされるかを変更したいと考えています。投影後の座標系はNDC(正規化されたデバイス座標)です。NDC をレンダリング サーフェスにマップする方法を制御する変換は、ビューポート変換です。へのパラメータによってビューポートの変換を制御しますglViewport()
。
ビューポートの寸法をレンダリング サーフェイスのサイズに設定すると、[-1.0, 1.0] の NDC 範囲がレンダリング サーフェイスにマップされます。その NDC 範囲のサブ範囲をサーフェスにレンダリングするには、指定されたビューポート サイズを適宜拡大する必要があります。元の画像の 1/4 をサーフェスの幅にマップするとします。ビューポートの幅をサーフェスの幅の 4 倍に設定します。
標準 NDC 範囲のサブ範囲をサーフェスにマッピングするには、ビューポートの原点も調整する必要があります。この場合、ビューポートの原点の値は負になります。前の例を続けると、画像の中央から始まる 1/4 または元の画像をマッピングするには、ビューポートの原点の x 値は、サーフェスの幅の -2 倍になります。
ビューポートを調整する必要がある方法について私が思いついたのは次のとおりです。次の定義を使用します。
winWidth: width of original window
winHeight: height of original window
xMin: minimum x-value of zoomed region in original window coordinates
xMax: maximum x-value of zoomed region in original window coordinates
yMin: minimum y-value of zoomed region in original window coordinates
yMax: maximum y-value of zoomed region in original window coordinates
fboWidth: width of FBO you use for rendering zoomed region
fboHeight: height of FBO you use for rendering zoomed region
歪みを避けるために、おそらく縦横比を維持したいと思うでしょう:
fboWidth / fboHeight = (xMax - xMin) / (yMax - yMin)
以下のすべてにおいて、ほとんどの演算 (特に除算) は浮動小数点で実行する必要があります。元の変数が整数の場合は、必ず型キャストを使用し、結果を丸めて整数に戻して最終結果を得てください。
xZoom = winWidth / (xMax - xMin);
yZoom = winHeight / (yMax - yMin);
vpWidth = xZoom * fboWidth;
vpHeight = yZoom * fboHeight;
xVp = -(xMin / (xMax - xMin)) * fboWidth;
yVp = -(yMin / (yMax - yMin)) * fboHeight;
glViewport(xVp, yVp, vpWidth, vpHeight);