混合処理


1.混合により可能な処理

1)トランスペアレンシィ(transparency;透明度)

 アルファ値を基に,物体に対して透明度を設定する(ガラスなどの表現).
 またトランスペアレンシィとテクスチュアマッピングを組み合わせることにより,特に樹木等,モデリングにより膨大な情報量となる場合の処理に有効である.
 

2)アンチエイリアシング(anti-aliasing)

 低解像度で画像計算した場合に発生するエイリアスを除去する技術。(別添資料参照)
 注) aliasとは..
 低解像度で画像を計算した場合に発生する現象であり,物体のエッジに生ずるジャギー(ギザギザ), 低速度で運動する物体輪郭の震動,ピクセル以下の大きさの物体が運動する際の点滅,高密度の連続パターンに生じるモアレなど複数の意味がある。
 

3)フォグ(fog; 霧)

 その名の通り,霧を表現する手法である.これにより,遠方のモデリングが不要となりデータ量を少なくすることができるとともに,より高い現実感を得ることができる.

 

2.トランスペアレンシィの設定

1)混合の関数を定める glBlendFunc sfactor, tfactor
   例)     glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

2)混合処理を有効にする. glEnable GL_BLEND

注)トランスペアレンシィを設定する物体に対しては,奥行判定(GL_DEPTH_TEST)が問題となる場合がある.
  そのため,透明度を設定する物体を最後に描画するようにすることが有効である.

3.アンチエイリアシングの設定

1)混合の関数を定める glBlendFunc sfactor, tfactor
   例)     glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

2)混合処理を有効にする. glEnalbe GL_BLEND

3)アンチエイリアシングの品質を決定する. glHint target, hint
  例)glHint GL_POLYGON_SMOOTH_HINT,GL_FASTEST

4)アンチエイリアシングを有効にする.
 例)glEnable GL_POLYGON_SMOOTH  'ポリゴンの場合
      glEnable GL_LINE_SMOOTH    '線の場合

注)アンチエイリアシングを用いる場合には奥行き判定(GL_DEPTH_TEST)は使えない.
   (glDisable GL_DEPTH_TEST としておく必要がある.)
  そのため,裏を向いているポリゴンを描画しないように,以下の設定をしておく.
      glCullFace GL_BACK   '裏を向いているポリゴンの情報は廃棄される.
        glEnable GL_CULL_FACE
  またアンチエイリアシングにより,描画速度はかなり遅くなる.(高速アニメーションには不適)

4.Fogの設定

1)Fogに関するパラメータ(関数,フォグの色,濃さ,距離等)を設定する.  glFogfv pname, param
  例)
   glFogfv GL_FOG_COLOR, fogclr(0)           'fogclr()はユーザーの定義した配列(コード参照)
    glFogfv GL_FOG_DENSITY, 0.3

2)Fogを有効にする.
  glEnable GL_FOG


 

5.コード例

'(C)Copyright Koji Makanae (makanae@mail.sp.myu.ac.jp)
Option Explicit
Dim m_hGLRC As Long
Private Type axis
    X As Single
    Y As Single
    z As Single
End Type
Private Type Texture
    tex() As Byte
    w As Integer
    h As Integer
End Type
Dim rot As axis
Dim tr As axis
Dim addr As axis
Dim addt As axis

'初期設定
Private Sub Form_Load()
    Timer1.Interval = 10
    Timer1.Enabled = False
End Sub
'タイマー起動
Private Sub Command2_Click()
    addr.Y = 5
    Timer1.Enabled = Not Timer1.Enabled
End Sub
Private Sub Picture1_Paint()
    display
End Sub

Private Sub SetView()
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    gluPerspective 50, Picture1.Width / Picture1.Height, 0.2, 10000
    glMatrixMode GL_MODELVIEW
    glViewport 0, 0, Picture1.Width, Picture1.Height
    glTranslatef 0, -1, -3
End Sub

Private Sub Form_Initialize()
    Initialize
End Sub

Private Function Initialize() As Boolean
    Dim pfd As PIXELFORMATDESCRIPTOR
    Dim R&
    Picture1.ScaleMode = vbPixels
 
    'set standard parameters
    pfd.nSize = Len(pfd)
    pfd.nVersion = 1
    pfd.dwFlags = PFD_SUPPORT_OPENGL Or PFD_DRAW_TO_WINDOW Or PFD_DOUBLEBUFFER Or PFD_TYPE_RGBA
    pfd.iPixelType = PFD_TYPE_RGBA
    pfd.cColorBits = 24
    pfd.cDepthBits = 16
    pfd.iLayerType = PFD_MAIN_PLANE
    R = ChoosePixelFormat(Picture1.hDC, pfd)
    If R = 0 Then
        MsgBox "ChoosePixelFormat failed"
        Exit Function
    End If
    R = SetPixelFormat(Picture1.hDC, R, pfd)
    'palette?
    m_hGLRC = wglCreateContext(Picture1.hDC)
    wglMakeCurrent Picture1.hDC, m_hGLRC
 
    'アンチエイリアスを使う場合,以下の2行は使えない.(コメントにする)
'    glDepthFunc GL_LEQUAL
'    glEnable GL_DEPTH_TEST

    glShadeModel GL_SMOOTH
 
    '混合の関数を指定する.
    glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
 
 
    'アンチエイリアスの品質
    glHint GL_POLYGON_SMOOTH_HINT, GL_NICEST
 
    '混合を有効にする.
'    glEnable GL_BLEND
 
    'アンチエリアスを有効にする.(ラインの場合)
    'glEnable GL_LINE_SMOOTH
    '(ポリゴンの場合)
    glEnable GL_POLYGON_SMOOTH
 
    'アンチエイリアスを用いる場合にはGL_DEPTH_TESTは使えない.
    'すなわち,奥行き情報はなくなるので注意.
    glDisable GL_DEPTH_TEST
 
    'GL_DEPTH_TESTが使えないので,
    '物体の表面以外の情報を廃棄(描画しない)するようにglCullFaceを
    '有効にする.
    glCullFace GL_BACK
    glEnable GL_CULL_FACE
 
    Dim fogclr(0 To 3) As Single
    fogclr(0) = 0.8
    fogclr(1) = 0.8
    fogclr(2) = 0.8
    fogclr(3) = 1
 
    'Fogを有効にする
    glFogfv GL_FOG_COLOR, fogclr(0)
    glFogfv GL_FOG_DENSITY, 0.3
    glEnable GL_FOG
 
    SetView
    SetLight
    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 SetLight()
    Dim ambientLight0(3) As Single
    Dim diffuseLight0(3) As Single
    Dim specularLight0(3) As Single
    Dim positionLight0(3) As Single
    'ライトの設定(平行光源)
    'fillarray4fはユーザー定義
    FillArray4f ambientLight0(), 0.2!, 0.2!, 0.2!, 1!   '環境光配列
    FillArray4f diffuseLight0(), 1!, 1!, 1!, 1!     '拡散光配列
    FillArray4f specularLight0(), 1!, 1!, 1!, 1!    '鏡面反射光配列
    FillArray4f positionLight0(), 0!, 1!, 1!, 0!    'ライトの位置配列(平行光源の場合,配列の4番目は0)
    glLightfv GL_LIGHT0, GL_AMBIENT, ambientLight0(0)    '環境光設定
    glLightfv GL_LIGHT0, GL_DIFFUSE, diffuseLight0(0)   '拡散光設定
    glLightfv GL_LIGHT0, GL_SPECULAR, specularLight0(0)  '鏡面反射光設定
    glLightfv GL_LIGHT0, GL_POSITION, positionLight0(0)   'ライトの位置設定
 
    'ライティングを使用可能に
    glEnable GL_LIGHTING
    glEnable GL_LIGHT0
'    glEnable GL_LIGHT1
End Sub

Public Sub display()
    glMatrixMode GL_MODELVIEW
    '背景色の設定
    glClearColor 0.8, 0.8, 0.9, 1
 
'    アンチエイリアシングを用いる場合には,GL_DEPTH_BUFFER_BITは無い.
    glClear GL_COLOR_BUFFER_BIT
 
    glLoadIdentity
 
    '視点の設定
    glTranslatef 0, -1, -5
    glRotatef 10, 1, 0, 0
    glRotatef rot.Y, 0, 1, 0
 
   '図形の描画
    glPushMatrix
        glTranslatef 0.5, -5, -5
        SetColor 0.01, 0.01, 0.03, 0.1, 0.1, 0.3, 0.1, 0.1, 0.25, 1
        glutSolidCube 10
    glPopMatrix
 
    glPushMatrix
        glTranslatef 0.5, 1, -5
        SetColor 0.01, 0.01, 0.03, 0.1, 0.1, 0.3, 0.1, 0.1, 0.25, 1
        glutSolidCube 3
    glPopMatrix
    glPushMatrix
        glRotatef -90, 1, 0, 0
        SetColor 0.01, 0.01, 0.01, 0.2, 0.2, 0.22, 0.2, 0.2, 0.22, 1
        glutSolidCone 0.7, 2, 10, 10
    glPopMatrix
    glPushMatrix
        glTranslatef -1, 0, -1
        SetColor 0.3, 0.05, 0.05, 0.3, 0.05, 0.05, 0.35, 0.1, 0.1, 0.8
        glutSolidSphere 0.7, 10, 10
    glPopMatrix
    SwapBuffers Picture1.hDC
End Sub

Private Sub SetColor(ambR!, ambG!, ambB!, difR!, difG!, difB!, specR!, specG!, specB!, alpha!)
    Dim MaterialAmbient(3) As Single
    Dim MaterialDiffuse(3) As Single
    Dim MaterialSpecular(3) As Single
 
    FillArray4f MaterialAmbient(), ambR, ambG, ambB, alpha
    FillArray4f MaterialDiffuse(), difR, difG, difB, alpha
    FillArray4f MaterialSpecular(), specR, specG, specB, alpha
    glMaterialfv GL_FRONT, GL_AMBIENT, MaterialAmbient(0)
    glMaterialfv GL_FRONT, GL_DIFFUSE, MaterialDiffuse(0)
    glMaterialfv GL_FRONT, GL_SPECULAR, MaterialSpecular(0)
End Sub

Private Sub Timer1_Timer()
    rot.Y = rot.Y + addr.Y
    DoEvents
    display
End Sub

Private Sub FillArray4f(A() As Single, f1 As Single, f2 As Single, f3 As Single, f4 As Single)
    A(0) = f1: A(1) = f2: A(2) = f3: A(3) = f4
End Sub