モデリング変換(2)


(前回のプリント修正)
        コード中の
        glutInitDisplayMode AUX_SINGLE Or AUX_RGBA
        → glutInitDisplayMode GLUT_SINGLE Or GLUT_RGBAに修正すること.
(補足)
   新規にプログラムを作成する場合に,参照設定でVB OpenGLを選択することを忘れないこと.
 

1.モデリング変換の考え方

    ユーザーインターフェースからの図形の移動命令(コード2)
   図形の移動と回転の組み合わせ(コード3〜コード6)
 

2.PushMatrixとPopMatrix

    glPushMatrix    現在の座標変換行列を記憶させる.
    glPopMatrix          記憶していた座標変換行列に戻す.
    利用方法:コード8・9
 
(演習問題)
プリント資料(OpenGL Programing Guide)に示される太陽系,ロボットアームの構造を理解し,
それを基にVisualBasic上でプログラミングしなさい.
 (aux...=glut....,ただし画面設定に関するコマンド,glutWireBoxコマンドはWindowsのOpenGLでは
  通用しないので注意)

 

(コード1)基本プログラム

'Form1上にPicture1及びCommand1を配置する.
Dim m_hGLRC&
Private Sub Form_Initialize()
    Initialize
    ViewSet 50, Picture1.ScaleWidth / Picture1.ScaleHeight, 1, 100
End Sub

Private Sub Picture1_Paint()
    Draw
End Sub

Private Sub Command1_Click()
    Draw
End Sub

Private Function Initialize() As Boolean
    Dim pfd As PIXELFORMATDESCRIPTOR
    Dim R&
    Picture1.ScaleMode = vbPixels
    glutInitDisplayMode GLUT_SINGLE Or GLUT_RGBA
    R = ChoosePixelFormat(Picture1.hDC, pfd)
    If R = 0 Then
        MsgBox "ChoosePixelFormat failed"
        Exit Function
    End If
    R = SetPixelFormat(Picture1.hDC, R, pfd)

    m_hGLRC = wglCreateContext(Picture1.hDC)
    wglMakeCurrent Picture1.hDC, m_hGLRC
    Initialize = True
End Function

Private Sub Form_Unload(Cancel As Integer)
    If m_hGLRC <> 0 Then
        wglMakeCurrent 0, 0
        wglDeleteContext m_hGLRC
    End If
End Sub

Private Sub ViewSet(fov As Single, aspect As Single, near As Single, far As Single)
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    gluPerspective fov, aspect, near, far
    glViewport 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight
    glMatrixMode GL_MODELVIEW
End Sub

Public Sub Draw()
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glTranslatef 0#, 0#, -3#
    glutWireCube 0.5
    glFlush
End Sub
 
 

(コード2)コマンドボタンを押すことにより,物体を移動する.

Dim tz As Single   'グローバル変数としてtzを宣言

Private Sub Command1_Click()
    tz = tz + 0.5
    Draw
End Sub

Public Sub Draw()
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glTranslatef 0#, 0#, -10 + tz
    glutWireCube 0.5
    glFlush
End Sub
 

(コード3)等間隔で物体を配置する.

Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glTranslatef 0#, 0.1, -5#
    glutWireCube 0.5
    For n = 1 To 100
        glTranslatef 0.3, 0.2, 0
        glutWireCube 0.5
    Next
    glFlush
End Sub
 

(コード4)円周上に物体を配置する.

Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glRotatef 10, 1, 0, 0
    glTranslatef 0#, -3, -5#
    glutWireCube 0.5
    For n = 1 To 100
        glRotatef 2, 0, 1, 0
        glTranslatef 0, 0, -0.5
        glutWireCube 0.5
    Next
    glFlush
End Sub
 

(コード5)図形を任意の座標を中心に回転させる.

(下のコードによれば直方体の中心で回転する.)
Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glTranslatef 0#, 0, -5#
    glutWireCube 1
    glRotatef 45, 0, 0, 1
    glScalef 0.2, 2, 0.2
    glutWireCube 0.5
    glFlush
End Sub
 

(コード6)直方体の下端を中心として回転させたい場合

Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glTranslatef 0#, 0, -5#
    glutWireCube 1
    glTranslatef 0, -0.5, 0  '物体
    glRotatef 45, 0, 0, 1
    glTranslatef 0, 0.5, 0
    glScalef 0.2, 2, 0.2
    glutWireCube 0.5
    glFlush
End Sub
 

(コード7)PushMatrix,PopMatrixを用いない場合の問題点

Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glRotatef 10, 1, 0, 0
    glTranslatef 0#, -3, -5#
    glScalef 0.2, 2, 0.2  'この時点で座標系のスケーリングが行なわれる.
    glutWireCube 0.5
 'スケール変換に応じた座標系の中での
   モデリングが行なわれることになる.
    For n = 1 To 100
        glRotatef 2, 0, 1, 0
        glTranslatef 0, 0, -0.5
        glutWireCube 0.5      
 Next
    glFlush
End Sub
 

(コード8)glPushMatrix, glPopMatrixの利用(1)

ある時点の座標変換を記憶させておき,必要時に戻す
Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glRotatef 10, 1, 0, 0
    glTranslatef 0#, -3, -5#
    glPushMatrix
        glScalef 0.2, 2, 0.2
        glutWireCube 0.5
    glPopMatrix
    For n = 1 To 100
        glRotatef 2, 0, 1, 0
        glTranslatef 0, 0, -0.5
        glutWireCube 0.5
    Next
    glFlush
End Sub
 

(コード9)glPushMatrix, glPopMatrixの利用(2)

Public Sub Draw()
    Dim n As Integer
    glClearColor 0, 0, 0, 0
    glClear GL_COLOR_BUFFER_BIT
    glColor3f 1#, 1#, 1#
    glLoadIdentity
    glRotatef 10, 1, 0, 0
    glTranslatef 0#, -3, -5#
    glPushMatrix
        glScalef 0.2, 2, 0.2
        glutWireCube 0.5
    glPopMatrix
    For n = 1 To 100
        glRotatef 2, 0, 1, 0
        glTranslatef 0, 0, -0.5
        glPushMatrix
            glScalef 0.2, 2, 0.2
            glutWireCube 0.5
        glPopMatrix
    Next
    glFlush
End Sub