io + OpenGL = ioDesktop でグラフを描く

キミならどう書く 2.0 - ROUND 3 - ? Lightweight Language Ring


例によって iolanguage にて。
ioDesktop では OpenGL を扱えるので、そっちで描画してみました。



graph.io

GLGraphApp := OpenGL clone do(
    width := 440; height := 320
    data := nil
    GW := 12
    
    font := Font clone open("resources/library/fonts/Free/Sans/Bold.ttf") setPixelSize(GW)
    
    display := method(
        glClear(GL_COLOR_BUFFER_BIT)
        
        if (0 < (data size),
            // グラフの全体を描画
            glBegin(GL_TRIANGLE_STRIP)
                glColor3f(0, 0, 1)  glVertex2f(16, 8)
                glColor3f(1, 0, 1)  glVertex2f(16, 8 + GW * (data size))
                glColor3f(0, 1, 1)  glVertex2f(width - 16, 8)
                glColor3f(1, 1, 1)  glVertex2f(width - 16, 8 + GW * (data size))
            glEnd
            
            // 各要素の余分な部分を塗りつぶす
            rate := (width - 32) / (data max abs + 1)
            data foreach(i, v,
                glBegin(GL_TRIANGLE_STRIP)
                    glColor3f(0, 0, 0)
                    glVertex2f(16 + v * rate, 8 + GW * i)
                    glVertex2f(16 + v * rate, 8 + GW * (i + 1))
                    glVertex2f(width - 16, 8 + GW * i)
                    glVertex2f(width - 16, 8 + GW * (i + 1))
                glEnd
                glPushMatrix
                    glTranslated(4, 10 + GW * i, 0)
                    glColor3f(1, 1, 1)
                    font drawString(v asString)
                glPopMatrix
            )
        )
        glFlush
        glutSwapBuffers
    )
    
    reshape := method(w, h,
        width = w
        height = h
        
        glLoadIdentity
        glViewport(0, 0, width, height)
        glOrtho(0, width, 0, height, 0.0, 1.0)
    )
    
    run := method(d,
        data = d
        
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH)
        glutInitWindowSize(width, height)
        
        glutInit
        glutCreateWindow("キミならどう書く 2.0 - ROUND 3 - by.SiroKuro")
        glutEventTarget(self)
        glutDisplayFunc
        glutReshapeFunc
        
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
        
        glutMainLoop
    )
)

// グラフで表示するデータをランダムに作成
data := List clone
Random setSeed(Date clone now asNumber)
for(i, 1, 25,
    data append(Random value(0, 320) floor)
)

GLGraphApp clone run(data)


面倒だったので、元データはプログラム中でランダムに作成しちゃいました。
引数からデータを取得して扱いたいときには、ランダムに作成している部分を

data := List clone
args slice(1) foreach(v,
    data append(Sequence clone appendSeq(v) asNumber)
)

に変更すればOKです。


使用したVMは http://www.mike-austin.com/io/ の IoFull-Cygwin-2006-04-20.zip
ダウンロード後、解凍して 『 $ iodesktop graph.io 』 みたいにすれば実行できるはずー。たぶん。