0

OpenGL SuperBible fram Addison-Wesleyを読んで読んだ:
glTranslate への各呼び出しは、modelview マトリックスに累積され
ます。これはどういう意味ですか?
たとえば、次のコードを意味します:

glTranslatef(2.0,3.0,0);
glTranslatef(4.0,5.0,0);  

最初に原点にあるオブジェクトをポイントに(2,3,0)移動し、次にそれを原点からではなく再び平行移動(2,3,0)(2+4,3+5,0+0) = (6,8,0)ますか?

glScalefこれはandについても当てはまりglRotatefますか?
たとえば、このコード:

glScalef(2.0,3.0,4.0);
glScalef(3.0,4.0,5.0);  

最初に1x1x1立方体を2x3x4立方体の長方形に変換し、次にこの立方体の長方形を1 に変換し6x12x20ますか?
最後に、このコードは x 軸を中心に合計 75 度回転することを意味しますか?

glRotatef(30.0,1,0,0);
glRotatef(45.0,1,0,0);  

最も重要なこと:これらの関数を呼び出す前に glLoadIdentity() を呼び出すと、これらの機能がキャンセルされますか? つまり、
このコードが毎回保証していると思いますか?translates will be done from the origin?scale changes will be done from the initial state?

void COpenGLControl::ZoomToFullExtent()
{
float zoom1 = (float)oglWindowWidth/(float)ImageWidth;
float zoom2 = (float)oglWindowHeight/(float)ImageHeight;
m_fZoom = min(zoom1,zoom2);
m_fZoomInverse = 1/m_fZoom;
m_fPosX = 0;
m_fPosY = 0;
OnDraw(NULL);
}  

void COpenGLControl::FixedZoomIn()
{
m_fZoom = 2*m_fZoom;
m_fZoomInverse = 1/m_fZoom;
OnDraw(NULL);
}

void COpenGLControl::FixedZoomOut()
{
m_fZoom = 0.5*m_fZoom;
m_fZoomInverse = 1/m_fZoom;
OnDraw(NULL);
}

void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if (WantToPan)
{
    if (m_fLastX < 0.0f && m_fLastY < 0.0f)
    {
        m_fLastX = (float)point.x;
        m_fLastY = (float)point.y;
    }
    diffX = (int)(point.x - m_fLastX);
    diffY = (int)(point.y - m_fLastY);
    m_fLastX = (float)point.x;
    m_fLastY = (float)point.y;
    if (nFlags & MK_MBUTTON)
    {
        m_fPosX += (float)0.2f*m_fZoomInverse*diffX;
        m_fPosY += (float)0.2f*m_fZoomInverse*diffY;
    }
    OnDraw(NULL);
}
CWnd::OnMouseMove(nFlags, point);
}  

void COpenGLControl::OnDraw(CDC *pDC)
{
// TODO: Camera controls
wglMakeCurrent(hdc,hrc);
glLoadIdentity();
gluLookAt(0,0,1,0,0,0,0,1,0);
glScalef(m_fZoom,m_fZoom,1.0);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
wglMakeCurrent(NULL, NULL);
}
4

3 に答える 3

0

OpenGl は、頂点の座標を乗算する modelView マトリックスを保持します。移動、回転、スケーリングなどを呼び出すたびに、この行列が右に乗算されます。あなたが持っている場合:

glLoadIdentity();
glTranslatef(2.0,3.0,0);
glTranslatef(4.0,5.0,0);  

結果は、最初に頂点を 4,5,0 で、次に 2,3,0 で変換します。内部的には、これは次のように機能します。 1. modelView マトリックスが ID になります。2. 現在の modelView マトリックス (単位元) は、値 (4、5、0) を持つ変換マトリックスで右乗算されます。詳細については、( http://en.wikipedia.org/wiki/Translation_%28geometry%29 )を参照してください。 3. 現在の modelViewmatrix (ステップ 2 の 1 つ) は、2 番目の変換行列で右に乗算されます。

スケーリングの例では:

glScalef(2.0,3.0,4.0);
glScalef(3.0,4.0,5.0);  

これは、最初に 1x1x1 の直方体を 3x4x5 の直方体に変換し、次に 6x12x20 に変換することと同じです。回転の場合、最初に 45 度回転し、次に 30 度回転します。

glLoadIdentity() の使用に関する質問に対して、modelView マトリックスは、マトリックスの前の値とは独立した ID になります。

また、opengl の変換スタック システムのチェックにも興味があるかもしれません。

于 2013-08-27T18:38:07.537 に答える
0

説明を含む OpenGL API 関数に特に注意してください: 「現在の... に ... を実行します」

OpenGL は美化されたステート マシンであり、バインドされたオブジェクトや行列 (従来の OpenGL の場合) などはその状態を保持します。これを呼び出すとglTranslatef (...)、現在のマトリックス (マトリックス モードとマトリックス スタックの一番上で定義) が乗算されます。glLoadMatrixf (...)を発行するglLoadIdentity (...)か、行列スタックを変更しない限り、glTranslatef (...)呼び出すたびに単純に蓄積されます。 現在の行列をそのアイデンティティ


glLoadIdentity (...)に置き換えます:

    1, 0, 0, 0
    0, 1, 0, 0
    0, 0, 1, 0
    0, 0, 0, 1

フレームごとに変換行列をセットアップする場合、通常、これを行う必要があります。それ以外の場合、すべての変換は以前の状態に関連します (ただし、これが望ましい場合もあります)。

于 2013-08-27T20:06:54.513 に答える