照光処理(ライティング)

 

1.照光モデルにおける光の分類

 放射光  emission

 環境光     ambient

 拡散光     diffuse

 鏡面光(鏡面反射)  specular

  →物体の色は光の特性及び物体の特性により決定される.

2.光源の種類

 平行光源

 点光源

 スポットライト

3.ライトの設定

    glLightfv light, pname, param

        lightはGL_LIGHT0, GL_LIGHT1, ・・・GL_LIGHT7まで
      pnameは設定項目  GL_AMBIENT等
      paramは設定した配列等
  
  例)
  glLightfv GL_LIGHT1, GL_AMBIENT, ambientLight1(0)    '環境光設定
    glLightfv GL_LIGHT1, GL_DIFFUSE, diffuseLight1(0)   '拡散光設定
    glLightfv GL_LIGHT1, GL_SPECULAR, specularLight1(0)  '鏡面反射光設定
    glLightfv GL_LIGHT1, GL_POSITION, positionLight1(0)   'ライトの位置設定
  
  詳細はコード参照

  光源の種類の設定
        GL_POSITIONで設定する照明位置の同次座標(x,y,z,w)のwの値により異なる.

    w=1:点光源
    w=0:平行光源

   例)
      positionLight1(0)=1
       positionLight1(1)=1
       positionLight1(2)=0
       positionLight1(3)=0      'ここの値が0であれば平行光源,1であれば点光源.
   glLightfv GL_LIGHT1, GL_POSITION, positionLight1(0)

   点光源の場合には照明位置は実座標として指定できる.また光は減衰する.
   平行光源の場合には距離は関係無く,無限遠にある光源(太陽)と考えるため光は減衰しない.
   (詳細は別添資料参照)

4.物体の色の指定

 
  それぞれの物体に対して環境光,拡散光,鏡面光(場合によっては放射光)を設定する.
  例)
   glMaterialfv GL_FRONT, GL_AMBIENT, MaterialAmbient(0)
    glMaterialfv GL_FRONT, GL_DIFFUSE, MaterialDiffuse(0)
    glMaterialfv GL_FRONT, GL_SPECULAR, MaterialSpecular(0)

  詳細はコード参照
 


コード  LIGHTING.VBP  (より詳細なプロパティを知るためには,http://www.myu.ac.jp/makanae/より
                  ソースコードをダウンロードしてください.)

lightmod.bas(標準モジュール)

'(C)Copyright Koji Makanae (makanae@mail.sp.myu.ac.jp)

Option Explicit
Public Const R = 0
Public Const G = 1
Public Const B = 2
Public Const A = 3
Public Const Amb = 0
Public Const Dif = 1
Public Const Spec = 2
Public Const Emit = 3
Public Const Back = 4
Public clr(0 To 4, 0 To 3)
Public clrindex As Integer



' lightfrm1.frm (Form1)

'(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 texground As Texture
Dim texsky As Texture
Dim rot As axis
Dim tr As axis
Dim addr As axis
Dim addt As axis

'初期設定
Private Sub Form_Load()
    Dim m As Integer, n As Integer
    Shape1(0).FillStyle = vbFSSolid
    Shape1(1).FillStyle = vbFSSolid
    Shape1(2).FillStyle = vbFSSolid
    Shape1(3).FillStyle = vbFSSolid
    Shape1(4).FillStyle = vbFSSolid
    clr(3, A) = 255
    For n = 0 To 2
        clr(n, R) = 70
        clr(n, G) = 70
        clr(n, B) = 80
    Next
    Shape1(0).FillColor = RGB(clr(0, R), clr(0, G), clr(0, B))
    Shape1(1).FillColor = RGB(clr(1, R), clr(1, G), clr(1, B))
    Shape1(2).FillColor = RGB(clr(2, R), clr(2, G), clr(2, B))
    Shape1(3).FillColor = RGB(clr(3, R), clr(3, G), clr(3, B))
    HScroll1.Value = clr(3, A)
    Timer1.Interval = 100
    Timer1.Enabled = False
    Command1.Caption = "Flat/Smooth"
    Check1(0).Value = 1: Check1(1).Value = 0
End Sub

'ライトの設定チェックボックス
Private Sub Check1_Click(Index As Integer)
    Select Case Index
        Case Is = 0
            If Check1(0).Value = 1 Then
                glEnable GL_LIGHT0
            Else
                glDisable GL_LIGHT0
            End If
        Case Is = 1
            If Check1(1).Value = 1 Then
                glEnable GL_LIGHT1
            Else
                glDisable GL_LIGHT1
            End If
    End Select

    '再描画
    display
End Sub
'シェーディング切り替え
Private Sub Command1_Click()
    Static smoothflag As Boolean
    smoothflag = Not smoothflag
    If smoothflag = True Then
        glShadeModel GL_SMOOTH
    Else
        glShadeModel GL_FLAT
    End If
    display
End Sub

'タイマー起動
Private Sub Command2_Click()
    addr.Y = 5
    Timer1.Enabled = Not Timer1.Enabled
End Sub

'色設定
Private Sub Command5_Click(Index As Integer)
    clrindex = Index
    Form2.HScroll1(0) = clr(clrindex, R)
    Form2.HScroll1(1) = clr(clrindex, G)
    Form2.HScroll1(2) = clr(clrindex, B)
    Form2.Show
End Sub

'アルファ設定
Private Sub HScroll1_Change()
    clr(1, A) = HScroll1.Value
    Print clr(1, A)
    display
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

    glDepthFunc GL_LEQUAL
    glEnable GL_DEPTH_TEST
    glShadeModel GL_FLAT
    glEnable GL_BLEND 'アルファを設定する場合,必要

    glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

    Initialize = True
    SetView
    SetLight
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()
    Dim MaterialAmbient(3) As Single
    Dim MaterialDiffuse(3) As Single
    Dim MaterialSpecular(3) As Single
    Dim MaterialEmission(3) As Single
    Dim ambientLight1(3) As Single
    Dim positionLight1(3) As Single
    Dim diffuseLight1(3) As Single
    Dim specularLight1(3) As Single

    glMatrixMode GL_MODELVIEW

    '背景色の設定
    glClearColor (clr(Back, R) / 255), (clr(Back, G) / 255), (clr(Back, B) / 255), 1

    glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT
    glLoadIdentity

    '視点の設定
    glTranslatef 0, -1, -5
    glRotatef 10, 1, 0, 0
    glRotatef rot.Y, 0, 1, 0

    'ライトの設定
    FillArray4f ambientLight1(), 0.2!, 0.2!, 0.2!, 1!   '環境光配列
    FillArray4f diffuseLight1(), 1!, 1!, 1!, 1!     '拡散光配列
    FillArray4f specularLight1(), 1!, 1!, 1!, 1!    '鏡面反射光配列
    FillArray4f positionLight1(), 0!, 1.5!, 1!, 1!    'ライトの位置配列
    glLightfv GL_LIGHT1, GL_AMBIENT, ambientLight1(0)    '環境光設定
    glLightfv GL_LIGHT1, GL_DIFFUSE, diffuseLight1(0)   '拡散光設定
    glLightfv GL_LIGHT1, GL_SPECULAR, specularLight1(0)  '鏡面反射光設定
    glLightfv GL_LIGHT1, GL_POSITION, positionLight1(0)   'ライトの位置設定

    If Check1(1).Value = 1 Then
        '描画用ライトオブジェクトの色を設定(Emission)
        SetColor 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1
        FillArray4f MaterialEmission(), 1#, 0.9, 0.7, 0#
        glMaterialfv GL_FRONT, GL_EMISSION, MaterialEmission(0)
        glPushMatrix
            glTranslatef 0, 1.5, 1
            glutSolidSphere 0.1, 10, 10
        glPopMatrix

        'Emissionの再設定(Emissionをゼロにする)
        FillArray4f MaterialEmission(), 0, 0, 0, 0
        glMaterialfv GL_FRONT, GL_EMISSION, MaterialEmission(0)
    End If

   '図形の描画
    glPushMatrix
        glTranslatef 0.5, 1, -5
        'SetColorサブプロシージャを用いた色設定
        SetColor 0.3, 0.05, 0.05, 0.3, 0.05, 0.05, 0.35, 0.1, 0.1, 1
        glutSolidCube 3
    glPopMatrix

    FillArray4f MaterialAmbient(), (clr(0, R) / 255), (clr(0, G) / 255), (clr(0, B) / 255), (clr(1, A) / 255)
    FillArray4f MaterialDiffuse(), (clr(1, R) / 255), (clr(1, G) / 255), (clr(1, B) / 255), (clr(1, A) / 255)
    FillArray4f MaterialSpecular(), (clr(2, R) / 255), (clr(2, G) / 255), (clr(2, B) / 255), (clr(1, A) / 255)
    FillArray4f MaterialEmission(), (clr(3, R) / 255), (clr(3, G) / 255), (clr(3, B) / 255), (clr(1, A) / 255)
    glMaterialfv GL_FRONT, GL_AMBIENT, MaterialAmbient(0)
    glMaterialfv GL_FRONT, GL_DIFFUSE, MaterialDiffuse(0)
    glMaterialfv GL_FRONT, GL_SPECULAR, MaterialSpecular(0)
    glMaterialfv GL_FRONT, GL_EMISSION, MaterialEmission(0)

    glPushMatrix
        glRotatef -90, 1, 0, 0
        glutSolidCone 0.7, 2, 10, 10
    glPopMatrix
    glPushMatrix
        glTranslatef -1, 0, -1
        glutSolidSphere 0.7, 10, 10
    glPopMatrix

    FillArray4f MaterialEmission(), 0, 0, 0, 0
    glMaterialfv GL_FRONT, GL_EMISSION, MaterialEmission(0)

    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
    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
 


'lgithfrm2.frm (Form2)

'(C)Copyright Koji Makanae (makanae@mail.sp.myu.ac.jp)
Option Explicit

Private Sub Command1_Click()
    Form2.Hide
    Call Form1.display
End Sub

Private Sub Form_Load()
    HScroll1(R).Min = 0: HScroll1(R).Max = 255
    HScroll1(G).Min = 0: HScroll1(G).Max = 255
    HScroll1(B).Min = 0: HScroll1(B).Max = 255
    Text1(R).Text = HScroll1(R).Value / 255
    Text1(G).Text = HScroll1(G).Value / 255
    Text1(B).Text = HScroll1(B).Value / 255
    Shape1.FillStyle = vbFSSolid
End Sub
Private Sub HScroll1_Change(Index As Integer)
    clr(clrindex, Index) = HScroll1(Index).Value
    Shape1.FillColor = RGB(HScroll1(0).Value, HScroll1(1).Value, HScroll1(2).Value)
    Form1.Shape1(clrindex).FillColor = RGB(HScroll1(0).Value, HScroll1(1).Value, HScroll1(2).Value)
    Text1(Index).Text = HScroll1(Index).Value / 255
    Form1.display
End Sub