Vala プログラミング

読者です 読者をやめる 読者になる 読者になる

Rust & Vala プログラミング

おながのブログ

Genie + OpenGL(Gtk.GLArea)2

f:id:onagat12:20151114174806p:plain

gtk3-demoにあるGLAreaデモをGenie言語で書き直しました。

(単独のプログラムは、gtk+-3.16ソース内のtestsにあります。testglarea.c

testglarea.gs(前回のプログラム)と同じglepoxy.vapiを使っています。

 

##glarea.gs

uses

    Gtk

    GL

 

init

    Gtk.init (ref args)

    var mainWindow = new MainWindow()

    mainWindow.show_all ()

    Gtk.main ()

 

class MainWindow : Window

    glarea : GLArea

    scale_x : Scale

    scale_y : Scale

    scale_z : Scale

    phi : float

    theta : float

    psi : float

 

    gl_vao : GLuint = 0

    gl_program : GLuint

    mvp_location : GLint

 

    init

        title = "GLArea Test"

        border_width = 12;

        destroy.connect (Gtk.main_quit)

 

        var box = new Box (Orientation.VERTICAL, 0)

        box.spacing = 6;

 

        glarea = new GLArea ()

        glarea.set_size_request (400, 400)

        glarea.render.connect (on_glarea_render)

 

        var controls = new Box (Orientation.VERTICAL, 0)

        var slider_x = new Box (Orientation.HORIZONTAL, 0)

        var slider_y = new Box (Orientation.HORIZONTAL, 0)

        var slider_z = new Box (Orientation.HORIZONTAL, 0)

 

        var label_x = new Label ("X axis ")

        var label_y = new Label ("Y axis ")

        var label_z = new Label ("Z axis ")

        scale_x = new Scale.with_range (Orientation.HORIZONTAL, 0, 360, 2)

        scale_y = new Scale.with_range (Orientation.HORIZONTAL, 0, 360, 2)

        scale_z = new Scale.with_range (Orientation.HORIZONTAL, 0, 360, 2)

        scale_x.value_changed.connect (on_value_changed)

        scale_y.value_changed.connect (on_value_changed)

        scale_z.value_changed.connect (on_value_changed)

 

        slider_x.pack_start (label_x, false, false, 0)

        slider_x.pack_start (scale_x)

        slider_y.pack_start (label_y, false, false, 0)

        slider_y.pack_start (scale_y)

        slider_z.pack_start (label_z, false, false, 0)

        slider_z.pack_start (scale_z)

 

        controls.pack_start (slider_x, false, false, 0)

        controls.pack_start (slider_y, false, false, 0)

        controls.pack_start (slider_z, false, false, 0)

 

        var button = new Button.with_label ("Quit")

        button.clicked.connect (Gtk.main_quit)

 

        box.pack_start (glarea, true, true)

        box.pack_start (controls, false, false)

        box.pack_start (button, false, false)

        add (box)

 

    def on_value_changed ()

        print("value-changed")

        phi = (float)scale_x.get_value ()

        theta = (float)scale_y.get_value ()

        psi = (float)scale_z.get_value ()

        print("phi: %f", phi)

        print("theta: %f", theta)

        print("psi: %f", psi)

 

        glarea.queue_render ()

 

    def on_realize (cntxt:Gdk.GLContext)

        print ("realize")

 

        gl_buffer : GLuint = 0

 

        vert_src : GLchar* = "#version 330\n \n in vec4 position;\n uniform mat4 mvp;\n void main() {\n gl_Position = mvp * position;\n }";

 

        frag_src : GLchar* = "#version 330\n \n out vec4 outputColor;\n void main() {\n outputColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n }";

 

        /// realize

        verts : array of float = { +0.0f, +1.0f, -1.0f, -1.0f, +1.0f, -1.0f}

 

        vert_shader : GLuint

        frag_shader : GLuint

        compileSuccess : GLint = 0

 

        vert_shader = glCreateShader (GL_VERTEX_SHADER);

        frag_shader = glCreateShader (GL_FRAGMENT_SHADER);

 

        glShaderSource(vert_shader, 1, &vert_src, null);

        glCompileShader(vert_shader);

        glGetShaderiv (vert_shader, GL_COMPILE_STATUS, out compileSuccess);

        if compileSuccess == GL_FALSE do print ("vert-shader Error")

 

        glShaderSource(frag_shader, 1, &frag_src, null);

        glCompileShader(frag_shader);

        glGetShaderiv (frag_shader, GL_COMPILE_STATUS, out compileSuccess);

        if compileSuccess == GL_FALSE do print ("frag-shader Error")

 

        gl_program = glCreateProgram();

        glAttachShader(gl_program, vert_shader);

        glAttachShader(gl_program, frag_shader);

        glLinkProgram(gl_program);

 

        mvp_location = glGetUniformLocation (gl_program, "mvp");

 

        glGenVertexArrays(1, out gl_vao);

        glBindVertexArray(gl_vao);

 

        glGenBuffers(1, out gl_buffer);

        glBindBuffer(GL_ARRAY_BUFFER, gl_buffer);

        glBufferData(GL_ARRAY_BUFFER, sizeof(float)*verts.length, verts, GL_STATIC_DRAW);

 

        glEnableVertexAttribArray(0);

        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

        glBindVertexArray(0);

 

        glDeleteBuffers(1, out gl_buffer);

 

    def on_glarea_render (cntxt:Gdk.GLContext): bool

        print ("render")

        on_realize (cntxt)

        /// render

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

 

        var mvp = new array of float[16]

        compute_mvp (out mvp, phi, theta, psi)

 

        glUseProgram(gl_program);

        glUniformMatrix4fv (mvp_location, 1, GL_FALSE, &mvp[0]);

        glBindVertexArray(gl_vao);

        glDrawArrays(GL_TRIANGLES, 0, 3);

 

        glBindVertexArray (0);

        glUseProgram (0);

 

        glFlush();

 

        return true

 

    def compute_mvp (out res:array of float, phi:float, theta:float, psi:float)

        print "compute mvp"

 

        res = new array of float[16]

        x : float = phi * ((float)Math.PI / 180.0f)

        y : float = theta * ((float)Math.PI / 180.0f)

        z : float = psi * ((float)Math.PI / 180.0f)

        print "x: %f", x

        print "y: %f", y

        print "z: %f", z

        c1:float = Math.cosf(x); s1:float = Math.sinf(x);

        c2:float = Math.cosf(y); s2:float = Math.sinf(y);

        c3:float = Math.cosf(z); s3:float = Math.sinf(z);

        var c3c2 = c3 * c2

        var s3c1 = s3 * c1

        var c3s2s1 = c3 * s2 * s1

        var s3s1 = s3 * s1

        var c3s2c1 = c3 * s2 * c1

        var s3c2 = s3 * c2

        var c3c1 = c3 * c1

        var s3s2s1 = s3 * s2 * s1

        var c3s1 = c3 * s1

        var s3s2c1 = s3 * s2 * c1

        var c2s1 = c2 * s1

        var c2c1 = c2 * c1

 

        res[0] = 1.0f; res[4] = 0.0f; res[8] = 0.0f; res[12] = 0.0f;

        res[1] = 0.0f; res[5] = 1.0f; res[9] = 0.0f; res[13] = 0.0f;

        res[2] = 0.0f; res[6] = 0.0f; res[10] = 1.0f; res[14] = 0.0f;

        res[3] = 0.0f; res[7] = 0.0f; res[11] = 0.0f; res[15] = 1.0f;

 

        res[0] = c3c2;  res[4] = s3c1 + c3s2s1; res[8] = s3s1 - c3s2c1; res[12] = 0.0f;

        res[1] = -s3c2; res[5] = c3c1 - s3s2s1; res[9] = c3s1 + s3s2c1; res[13] = 0.0f;

        res[2] = s2;      res[6] = -c2s1;              res[10] = c2c1;              res[14] = 0.0f;

        res[3] = 0.0f;   res[7] = 0.0f;                  res[11] = 0.0f;               res[15] = 1.0f;

 

 

ビルド

valac --vapidir=vapi --pkg gtk+-3.0 --pkg glepoxy -X -lepoxy -X -lm glarea.gs

Glibの数学ライブラリを使用しているので、 “-X -lm”のオプションを入れています。