OpenGL 回転と隠面処理 - Ruby

回転

 回転したときにX,Y,Z軸がどうなるか確認したいので、XZ平面とYZ平面を用意した。キーボードの入力h,lでY軸を中心とした回転(横回転)、j,kでX軸を中心とした回転(縦回転)を行う。
 軸を中心に回転...aa-ややこしい。
 angle には回転角度、x, y, zには回転方向を指定する。

        GL.Rotate(angle, x, y, z)

        # X軸を中心に30度回転
        # GL.Rotate(30, 1.0, 0.0, 0.0)

隠面処理(陰面処理?)

 視点から見て平面の陰になっている部分を描画しないために、GL_DEPTH_TESTを指定する。

        #隠面処理の有効範囲
        GL.Enable(GL::GL_DEPTH_TEST)

        # ... ここに隠面処理したい部分

        #隠面処理おわり
        GL.Disable(GL::GL_DEPTH_TEST)

ソース Ruby

Pythonで書いたものはこっち

require 'rubygems'
require 'opengl'
require 'glut'

class Sample

    def display()
        GL.Clear(GL::GL_COLOR_BUFFER_BIT | GL::GL_DEPTH_BUFFER_BIT)
        GL.LoadIdentity()
        # GLU.LookAt(0.0, 0.0, 1.0,
        #            0.0, 0.0, 0.0,
        #            0.0, 1.0, 0.0)

        # Y軸を中心として回転(横回転)
        GL.Rotate(@rotateX, 0.0, 1.0, 0.0)
        # X軸を中心として回転(縦回転)
        GL.Rotate(@rotateY, 1.0, 0.0, 0.0)

        #隠面処理の有効範囲
        GL.Enable(GL::GL_DEPTH_TEST)

        # X-Z
        GL.Begin(GL::GL_QUADS)
        GL.Color3d(1.0,0.0,0.0)
        GL.Vertex3f(-0.5,0.0,-0.5)
        GL.Vertex3f(0.5,0.0,-0.5)
        GL.Vertex3f(0.5,0.0,0.5)
        GL.Vertex3f(-0.5,0.0,0.5)
        
        # Y-Z
        GL.Color3d(0.0,1.0,0.0)
        GL.Vertex3f(0.0,-0.5,-0.5)
        GL.Vertex3f(0.0,0.5,-0.5)
        GL.Vertex3f(0.0,0.5,0.5)
        GL.Vertex3f(0.0,-0.5,0.5)
        GL.End()

        #隠面処理おわり
        GL.Disable(GL::GL_DEPTH_TEST)

        # GL.Flush()は使わない
        GLUT.SwapBuffers()
    end
    
    def keyboard(key,x,y)
        spd = 5
        # keyboard: Esc
        if key == 27 then exit() end
        # keyboard: l
        if key == 108 then @rotateX -= spd end
        # keyboard: h
        if key == 104 then @rotateX += spd end
        # keyboard: j
        if key == 106 then @rotateY -= spd end
        # keyboard: k
        if key == 107 then @rotateY += spd end
    end

    def repaint()
        # 再描画
        GLUT.PostRedisplay()
    end

    def initialize()

        @rotateX = 10
        @rotateY = 10

        GLUT.InitWindowPosition(100,100)
        GLUT.InitWindowSize(320,240)
        GLUT.Init
        GLUT.InitDisplayMode(GLUT::GLUT_DOUBLE | GLUT::GLUT_RGB | GLUT::GLUT_DEPTH)
        GLUT.CreateWindow("ruby-opengl 01")

        GLUT.DisplayFunc(method(:display).to_proc())
        GLUT.KeyboardFunc(method(:keyboard).to_proc())

        # repaint
        GLUT.IdleFunc(method(:repaint).to_proc())

        GL.ClearColor(1.0, 1.0, 1.0, 1.0)
    end

    def start()
        GLUT.MainLoop()
    end
end

Sample.new().start()