gtk3-demoにあるGLAreaデモをGenie言語で書き直しました。
(単独のプログラムは、gtk+-3.16ソース内のtestsにあります。testglarea.c)
*testglarea.gs(前回のプログラム)と同じglepoxy.vapiを使っています。
##glarea.gs
uses
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”のオプションを入れています。