Vala OepnGL ( ValaGL MatrixMath.vala )
ValaGL MatrixMath.vala の演算
Mat3(3x3 行列)
Mat3 の定義
struct Mat3
メンバー
float data[9]
Mat3 の各要素
m11(data[0]), m12(data[3]), m13(data[6])
m21(data[1]), m22(data[4]), m23(data[7])
m31(data[2]), m32(data[5]), m33(data[8])
メソッド
*生成
Mat3()
要素が 0 値の Mat3 を生成
(Creates a new matrix, zero initialized.)
Mat3.from_data (GLfloat a11, GLfloat a12, GLfloat a13,
GLfloat a21, GLfloat a22, GLfloat a23,
GLfloat a31, GLfloat a32, GLfloat a33)
要素が、以下のようになる Mat3 を生成
m11 = a11, m12 = a12, m13 = a13
m21 = a21, m22 = a22, m23 = a23
m31 = a31, m32 = a32, m33 = a33
(Creates a matrix whose contents are the copy of the given data.
Warning: the data are specified in column-first-index order,
which is different from the internal storage format
(row-first-index).)
Mat3.from_vec_mul (ref Vec3 a, ref Vec3 b)
2つの Vec3 a, b から Mat3 を生成(a * bT の計算、bT は b の
転置ベクトル)
m11 = a.x * b.x, m12 = a.x * b.y, m13 = a.x * b.z
m21 = a.y * b.x, m22 = a.y * b.y, m23 = a.y * b.z
m31 = a.z * b.x, m32 = a.z * b.y, m33 = a.z * b.z
(Given two vectors a and b, computes a matrix equal to a * bT.)
Mat3.from_array (GLfloat data)
要素が配列 data で与えられる Mat3 を生成
m11 = data[0], m12 = data[3], m13 = data[6]
m21 = data[1], m22 = data[4], m23 = data[7]
m31 = data[2], m32 = data[5], m33 = data[8]
(Creates a matrix whose contents are the copy of the given
array,assumed to have at least 9 elements.)
Mat3.identity ()
単位行列を生成
m11 = 1, m12 = 0, m13 = 0
m21 = 0, m22 = 1, m23 = 0
m31 = 0, m32 = 0, m33 = 1
(Creates an identity matrix.)
*ベクトル演算
void add (ref Mat3 other)
this(インスタンス)と other 行列との和(要素間の和)
(Adds the given matrix, component-wise.)
void sub (ref Mat3 other)
this(インスタンス)と other 行列との差(要素間の差)
this から other 行列を引く
(Subtracts the given matrix, component-wise.)
void mul (GLfloat factor)
this(インスタンス)の各要素をfactor倍する
(Multiplies the matrix by the given scalar, component-wise.)
void div (GLfloat factor)
this(インスタンス)の各要素をfactorで割る
(Divides the matrix by the given scalar, component-wise.)
void mul_mat (ref Mat3 other)
this(インスタンス、Mat3)と other 行列(Mat3)の積
( this × other )
m11 = m11*other11 + m12*other21 + m13*other31
m12 = m11*other12 + m12*other22 + m13*other32
m13 = m11*other13 + m12*other23 + m13*other33
m21 = m21*other11 + m22*other21 + m23*other31
m22 = m21*other12 + m22*other22 + m23*other32
m23 = m21*other13 + m22*other23 + m23*other33
m31 = m31*other11 + m32*other21 + m33*other31
m32 = m31*other12 + m32*other22 + m33*other32
m33 = m31*other13 + m32*other23 + m33*other33
(Multiplies the given matrix using the linear algebra definition
of matrix multiplication.)
Vec3 mul_vec (ref Vec3 vec)
this(インスタンス, Mat3)と vec ベクトル(Vec3) の積
( this × vec )
生成されるベクトル(Vec3): v
v.x = m11*vec.x + m12*vec.y + m13*vec.z
v.y = m21*vec.x + m22*vec.y + m23*vec.z
v.z = m31*vec.x + m32*vec.y + m33*vec.z
(Multiplies this matrix by the given vector and returns the result
as a new vector.)
Mat3 transposed ()
this(インスタンス, Mat3)の転置行列を生成
生成される転置行列(Mat3): A
a11 = m11, a12 = m21, a13 = m31
a21 = m12, a22 = m22, a23 = m32
a31 = m13, a32 = m23, a33 = m33
Returns a new matrix that is the transposition of this matrix.
GLfloat det ()
this(インスタンス, Mat3)の行列式を計算
行列式の値: D
D = m11*(m22*m31 - m32*m23) - m12*(m21*m33 - m31*m23)
+ m13*(m21*m32 - m31*m22)
Computes the determinant of this matrix.
Mat3 inverted (out bool success)
this(インスタンス, Mat3)の逆行列を生成
this(インスタンス)の行列式の値: D
生成される逆行列(Mat3): A
逆行列が存在しない場合(D = 0)、success に "false" が設定
される。
逆行列が存在する場合(D ≠ 0)、success に "true" が設定され、
逆行列が生成される。
a11 = (m22*m33 - m32*m23) / D
a12 = -(m12*m33 - m32*m13) / D
a13 = (m12*m23 - m22*m13) / D
a21 = -(m21*m33 - m31*m23) / D
a22 = (m11*m33 - m31*m13) / D
a23 = -(m11*m23 - m21*m13) / D
a31 = (m21*m32 - m31*m22) / D
a32 = -(m11*m32 - m31*m12) / D
a33 = (m11*m22 - m21*m12) / D
Returns a new matrix that is the inversion of this matrix.
@param success Set to ``false`` if the matrix cannot be inverted
(its determinant is zero) and ``true`` otherwise.
@return The inverted matrix if the matrix was successfully
inverted, otherwise the return value is undefined.
1 ベクトルの生成
## prog1
## main.vala
// Mat3 生成
using ValaGL.Core;
void main () {
var a = Mat3 ();
// a11(data[0])= 0, a12(data[3])= 0, a13(data[6])= 0
// a21(data[1])= 0, a22(data[4])= 0, a23(data[7])= 0
// a31(data[2])= 0, a32(data[5])= 0, a33(data[8])= 0
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a = Mat3.from_data (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f,
7.0f, 8.0f, 9.0f);
// a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
// a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
// a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
var va = Vec3.from_data (1.0f, 2.0f, 3.0f);
var vb = Vec3.from_data (4.0f, 5.0f, 6.0f);
a = Mat3.from_vec_mul (ref va, ref vb);
// a11(data[0])= 4, a12(data[3])= 5, a13(data[6])= 6
// a21(data[1])= 8, a22(data[4])= 10, a23(data[7])= 12
// a31(data[2])= 12, a32(data[5])= 15, a33(data[8])= 18
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
float d_array = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
a = Mat3.from_array (d_array);
// a11(data[0])= 1, a12(data[3])= 4, a13(data[6])= 7
// a21(data[1])= 2, a22(data[4])= 5, a23(data[7])= 8
// a31(data[2])= 3, a32(data[5])= 6, a33(data[8])= 9
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a = Mat3.identity ();
// a11(data[0])= 1, a12(data[3])= 0, a13(data[6])= 0
// a21(data[1])= 0, a22(data[4])= 1, a23(data[7])= 0
// a31(data[2])= 0, a32(data[5])= 0, a33(data[8])= 1
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
}
実行結果
Mat3 A
a11=0.000000 a12=0.000000 a13=0.000000
a21=0.000000 a22=0.000000 a23=0.000000
a31=0.000000 a32=0.000000 a33=0.000000
Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000
Mat3 A
a11=4.000000 a12=5.000000 a13=6.000000
a21=8.000000 a22=10.000000 a23=12.000000
a31=12.000000 a32=15.000000 a33=18.000000
Mat3 A
a11=1.000000 a12=4.000000 a13=7.000000
a21=2.000000 a22=5.000000 a23=8.000000
a31=3.000000 a32=6.000000 a33=9.000000
Mat3 A
a11=1.000000 a12=0.000000 a13=0.000000
a21=0.000000 a22=1.000000 a23=0.000000
a31=0.000000 a32=0.000000 a33=1.000000
2 ベクトル演算
## prog2
## main.vala
// Mat3 ベクトル演算 1
using ValaGL.Core;
void main () {
var a = Mat3.from_data (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f,
7.0f, 8.0f, 9.0f);
var b = Mat3.from_data (9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f,
3.0f, 2.0f, 1.0f);
a.add (ref b);
// a11(data[0])= 10, a12(data[3])= 10, a13(data[6])= 10
// a21(data[1])= 10, a22(data[4])= 10, a23(data[7])= 10
// a31(data[2])= 10, a32(data[5])= 10, a33(data[8])= 10
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a.sub (ref b);
// a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
// a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
// a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a.mul (2.0f);
// a11(data[0])= 2, a12(data[3])= 4, a13(data[6])= 6
// a21(data[1])= 8, a22(data[4])= 10, a23(data[7])= 12
// a31(data[2])= 14, a32(data[5])= 16, a33(data[8])= 18
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a.div (2.0f);
// a11(data[0])= 1, a12(data[3])= 2, a13(data[6])= 3
// a21(data[1])= 4, a22(data[4])= 5, a23(data[7])= 6
// a31(data[2])= 7, a32(data[5])= 8, a33(data[8])= 9
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
a.mul_mat (ref b);
// a11(data[0])= 30, a12(data[3])= 24, a13(data[6])= 18
// a21(data[1])= 84, a22(data[4])= 69, a23(data[7])= 54
// a31(data[2])= 138, a32(data[5])= 114, a33(data[8])= 90
stdout.printf ("Mat3 A\n");
stdout.printf ("a11=%f a12=%f a13=%f \n", a.data[0], a.data[3],
a.data[6]);
stdout.printf ("a21=%f a22=%f a23=%f \n", a.data[1], a.data[4],
a.data[7]);
stdout.printf ("a31=%f a32=%f a33=%f \n", a.data[2], a.data[5],
a.data[8]);
stdout.printf ("\n");
}
実行結果
Mat3 A
a11=10.000000 a12=10.000000 a13=10.000000
a21=10.000000 a22=10.000000 a23=10.000000
a31=10.000000 a32=10.000000 a33=10.000000
Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000
Mat3 A
a11=2.000000 a12=4.000000 a13=6.000000
a21=8.000000 a22=10.000000 a23=12.000000
a31=14.000000 a32=16.000000 a33=18.000000
Mat3 A
a11=1.000000 a12=2.000000 a13=3.000000
a21=4.000000 a22=5.000000 a23=6.000000
a31=7.000000 a32=8.000000 a33=9.000000
Mat3 A
a11=30.000000 a12=24.000000 a13=18.000000
a21=84.000000 a22=69.000000 a23=54.000000
a31=138.000000 a32=114.000000 a33=90.000000
3 ベクトル演算2
## prog3
## main.vala
// Mat3 ベクトル演算 2
using ValaGL.Core;
void main () {
var a = Mat3.from_data (2.0f, -2.0f, 3.0f, 1.0f, 1.0f, 1.0f,
1.0f, 3.0f, -1.0f);
var va = Vec3.from_data (1.0f, 2.0f, 3.0f);
//Vec3 mul_vec (ref Vec3 vec)
Vec3 vb = a.mul_vec (ref va);
// vb.x = 7, vb.y = 6, vb.z = 4
stdout.printf ("Vec3 vb\n");
stdout.printf ("vb.x=%f vb.y=%f vb.z=%f \n", vb.x, vb.y, vb.z);
stdout.printf ("\n");
//Mat3 transposed ()
Mat3 b = a.transposed ();
// b11(data[0])= 2, b12(data[3])= 1, b13(data[6])= 1
// b21(data[1])= -2, b22(data[4])= 1, b23(data[7])= 3
// b31(data[2])= 3, b32(data[5])= 1, b33(data[8])= -1
stdout.printf ("Mat3 B\n");
stdout.printf ("b11=%f b12=%f b13=%f \n", b.data[0], b.data[3],
b.data[6]);
stdout.printf ("b21=%f b22=%f b23=%f \n", b.data[1], b.data[4],
b.data[7]);
stdout.printf ("b31=%f b32=%f b33=%f \n", b.data[2], b.data[5],
b.data[8]);
stdout.printf ("\n");
//GLfloat det ()
float det = a.det ();
// det = -6
stdout.printf ("float Det\n");
stdout.printf ("det =%f\n", det);
stdout.printf ("\n");
//Mat3 inverted (out bool success)
bool success;
b = a.inverted (out success);
// success
// b11(data[0])= 4/6, b12(data[3])= -7/6, b13(data[6])= 5/6
// b21(data[1])= -2/6, b22(data[4])= 5/6, b23(data[7])= -1/6
// b31(data[2])= -2/6, b32(data[5])= 8/6, b33(data[8])= -4/6
// not success
// b11(data[0])= 0, b12(data[3])= 0, b13(data[6])= 0
// b21(data[1])= 0, b22(data[4])= 0, b23(data[7])= 0
// b31(data[2])= 0, b32(data[5])= 0, b33(data[8])= 0
stdout.printf ("Mat3 B\n");
if (success == false) {stdout.printf ("not success\n");}
else {stdout.printf ("success\n");}
stdout.printf ("b11=%f b12=%f b13=%f \n", b.data[0], b.data[3],
b.data[6]);
stdout.printf ("b21=%f b22=%f b23=%f \n", b.data[1], b.data[4],
b.data[7]);
stdout.printf ("b31=%f b32=%f b33=%f \n", b.data[2], b.data[5],
b.data[8]);
}
実行結果
Vec3 vb
vb.x=7.000000 vb.y=6.000000 vb.z=4.000000
Mat3 B
b11=2.000000 b12=1.000000 b13=1.000000
b21=-2.000000 b22=1.000000 b23=3.000000
b31=3.000000 b32=1.000000 b33=-1.000000
float Det
det =-6.000000
Mat3 B
success
b11=0.666667 b12=-1.166667 b13=0.833333
b21=-0.333333 b22=0.833333 b23=-0.166667
b31=-0.333333 b32=1.333333 b33=-0.666667
ビルド
valac --vapidir=./ --pkg glepoxy -X -lm main.vala MatrixMath.vala
Vala OpenGL ( ValaGL MatrixMath.vala)
ValaGL MatrixMath.vala の演算
Vec4 ( 4次元ベクトル)
Vec4の定義
struct Vec4
*4次元ベクトル
メンバー
GLfloat data[4]
メソッド
*生成
Vec4()
要素が 0 値の Vec4 を生成 (Creates a new vector, zero initialized.)
Vec4.from_data (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
要素が {x, y, z, w} の Vec4 を生成
(Creates a vector whose contents are the copy of the given data.)
Vec4.from_array (GLfloat[] data)
要素が配列 data で与えられる Vec4 を生成
(Creates a vector whose contents are the copy of the given array.)
Vec4.expand (ref Vec3 vec3, GLfloat w)
要素が {vec3.x, vec3.y, vec3.z, w} の Vec4 を生成
(Expands a 3x3 vector plus scalar into a 4x4 vector.)
*要素間の演算
void add (ref Vec4 other)
this(インスタンス)と other ベクトルとの和
(Adds the given vector, component-wise.)
void sub (ref Vec4 other)
this(インスタンス)から other ベクトルを引く
(Subtracts the given vector, component-wise.)
void mul_vec (ref Vec4 other)
this(インスタンス)と other ベクトルとの積
(Multiplies the given vector, component-wise.)
void div_vec (ref Vec4 other)
this(インスタンス)を other ベクトルで割る
(Divides the given vector, component-wise.)
*ベクトル演算
GLfloat dot_product (ref Vec4 other)
this(インスタンス)と other ベクトルの内積
(Computes the dot product of this vector and the other vector.)
void mul (GLfloat factor)
this(インスタンス)の各要素を factor 倍する
(Multiplies the vector by the given scalar.)
void div (GLfloat factor)
this(インスタンス)の各要素を factor で割る
(Divides the vector by the given scalar.)
GLfloat norm ()
this(インスタンス)ベクトルの大きさを求める
(Computes the norm of this vector.)
void normalize ()
this(インスタンス)ベクトルを規格化する
(Normalizes this vector, dividing it by its norm.
If the norm is zero, the result is undefined.)
*アクセッサー(ゲッター)
GLfloat x
data[0] へのアクセッサー
(Convenience accessor for data[0].)
GLfloat y
data[1] へのアクセッサー
(Convenience accessor for data[1].)
GLfloat z
data[2] へのアクセッサー
(Convenience accessor for data[2].)
GLfloat w
data[3] へのアクセッサー
(Convenience accessor for data[3].)
1 ベクトルの生成
## prog1.vala
using ValaGL.Core;
void main () {
var a = Vec4.from_data (1.0f, 2.0f, 3.0f, 4.0f);
// a.x(data[0])= 1.0, a.y(data[1])= 2.0
// a.z(data[2])= 3.0, a.w(data[3])= 4.0
stdout.printf ("Vec4 a x:%f y:%f z:%f w:%f\n", a.data[0], a.data[1], a.data[2], a.data[3]);
stdout.printf ("Vec4 a x:%f y:%f z:%f w:%f\n", a.x, a.y, a.z, a.w);
stdout.printf("\n");
var c = Vec3.from_data (5.0f, 6.0f, 7.0f);
stdout.printf ("Vec3 c x:%f y:%f z:%f\n", c.x, c.y, c.z);
var b = Vec4.expand (ref c, 8.0f);
// b.x = 5.0, b.y = 6.0, b.z = 7.0, b.w = 8.0
stdout.printf ("Vec4 b x:%f y:%f z:%f w:%f\n", b.x, b.y, b.z, b.w);
}
実行結果
Vec4 a x:1.000000 y:2.000000 z:3.000000 w:4.000000
Vec4 a x:1.000000 y:2.000000 z:3.000000 w:4.000000
Vec3 c x:5.000000 y:6.000000 z:7.000000
Vec4 b x:5.000000 y:6.000000 z:7.000000 w:8.000000
2 ベクトル演算
## prog2.vala
using ValaGL.Core;
void main () {
var a = Vec4.from_data (1.0f, 2.0f, 3.0f, 4.0f);
stdout.printf ("Vec4 a x:%f y:%f z:%f w:%f\n", a.x, a.y, a.z, a.w);
var b = Vec4.from_data (8.0f, 7.0f, 6.0f, 5.0f);
stdout.printf ("Vec4 b x:%f y:%f z:%f w:%f\n", b.x, b.y, b.z, b.w);
stdout.printf("\n");
float s = a.dot_product (ref b);
// s = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w
stdout.printf("s: %f\n", s);
stdout.printf("\n");
float a_norm = a.norm ();
// a_norm = SQRT(a.x*a.x + a.y*a.y + a.z*a.z + a.w*a.w)
stdout.printf("a_norm: %f\n", a_norm);
stdout.printf("\n");
a.normalize ();
// a.x = a.x/a.norm(), a.y = a.y/a.norm()
// a.z = a.z/a.norm(), a.w = a.w/a.norm()
stdout.printf("a x:%f y:%f z:%f w:%f\n", a.x, a.y, a.z, a.w);
a_norm = a.norm ();
stdout.printf("a_norm: %f\n", a_norm);
}
実行結果
Vec4 a x:1.000000 y:2.000000 z:3.000000 w:4.000000
Vec4 b x:8.000000 y:7.000000 z:6.000000 w:5.000000
s: 60.000000
a_norm: 5.477226
a x:0.182574 y:0.365148 z:0.547723 w:0.730297
a_norm: 1.000000
ビルド
valac --vapidir=./ --pkg glepoxy -X -lm main.vala MatrixMath.vala
Vala OpenGL ( ValaGL MatrixMath.vala )
ValaGL MatrixMath.vala の演算
前回のブログで使用した、ValaGL MatrixMath.vala の演算について書いています。
今回は、Vec3 ( 3次元ベクトル)です。
Vec3の定義
struct Vec3
メンバー
GLfloat data[3]
メソッド
* 生成
Vec3()
要素が 0 値の Vec3 を生成
( Creates a new vector, zero initialized. )
Vec3.from_data (GLfloat x, GLfloat y, GLfloat z)
要素が {x, y, z} の Vec3 を生成
( Creates a vector whose contents are the copy of the given data. )
Vec3.from_array (GLfloat data)
要素が配列 data で与えられる Vec3 を生成
( Creates a vector whose contents are the copy of the given array. )
* 要素間の演算
void add (ref Vec3 other)
this(インスタンス)と other ベクトルとの和(要素間の和)
( Adds the given vector, component-wise. )
void sub (ref Vec3 other)
this(インスタンス)から other ベクトルを引く(要素間の差)
( Subtracts the given vector, component-wise. )
void mul_vec (ref Vec3 other)
this(インスタンス)と other ベクトルの積(要素間の積)
( Multiplies the given vector, component-wise. )
void div_vec (ref Vec3 other)
this(インスタンス)を other ベクトルで割る(要素間の商)
( Divides the given vector, component-wise. )
* ベクトル演算
GLfloat dot_product (ref Vec3 other)
this(インスタンス)と other ベクトルの内積
( Computes the dot product of this vector and the other vector. )
Vec3 cross_product (ref Vec3 other)
this(インスタンス)と other ベクトルの外積(thisベクトル ✖️ otherベクトル)
( Computes the cross product of this vector and the other vector. )
void mul (GLfloat factor)
this(インスタンス)の各要素をfactor倍する
( Multiplies the vector by the given scalar. )
void div (GLfloat factor)
this(インスタンス)の各要素をfactorで割る
( Divides the vector by the given scalar. )
GLfloat norm ()
this(インスタンス)ベクトルの大きさを求める
( Computes the norm of this vector. )
void normalize ()
this(インスタンス)ベクトルを規格化する
( Normalizes this vector, dividing it by its norm.
If the norm is zero, the result is undefined. )
*アクセッサー(ゲッター)
GLfloat x
data[0]へのアクセッサー
( Convenience accessor for data[0]. )
GLfloat y
data[1]へのアクセッサー
( Convenience accessor for data[1]. )
GLfloat z
data[2]へのアクセッサー
( Convenience accessor for data[2]. )
1 ベクトルの生成
## prog1.vala
using ValaGL.Core;
void main () {
var a = Vec3 ();
// a.data[0] = 0, a.data[1] = 0, a.data[2] = 0
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.data[0], a.data[1], a.data[2]);
stdout.printf("\n");
var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
// b.x(data[0]) = 1.0, b.y(data[1]) = 2.0, b.z(data[2]) = 3.0
stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.data[0], b.data[1], b.data[2]);
stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
stdout.printf("\n");
float d = {4.0f, 5.0f, 6.0f};
var c = Vec3.from_array (d);
// c.x = 4.0, c.y = 5.0, c.z = 6.0
stdout.printf ("Vec3 c x:%f y:%f z:%f\n", c.x, c.y, c.z);
}
実行結果
Vec3 a x:0.000000 y:0.000000 z:0.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000
Vec3 c x:4.000000 y:5.000000 z:6.000000
2 要素間の演算
## prog2.vala
using ValaGL.Core;
void main () {
var a = Vec3.from_data (4.0f, 5.0f, 6.0f);
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
stdout.printf("\n");
a.add (ref b);
// a.x = a.x + b.x, a.y = a.y + b.y, a.z = a.z + b.z
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
a.sub (ref b);
// a.x = a.x - b.x, a.y = a.y - b.y, a.z = a.z - b.z
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
a.mul_vec (ref b);
// a.x = a.x * b.x, a.y = a.y * b.y, a.z = a.z * b.z
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
a.div_vec (ref b);
// a.x = a.x / b.x, a.y = a.y / b.y, a.z = a.z / b.z
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
}
実行結果
Vec3 a x:4.000000 y:5.000000 z:6.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000
Vec3 a x:5.000000 y:7.000000 z:9.000000
Vec3 a x:4.000000 y:5.000000 z:6.000000
Vec3 a x:4.000000 y:10.000000 z:18.000000
Vec3 a x:4.000000 y:5.000000 z:6.000000
3 ベクトル演算
## prog3.vala
using ValaGL.Core;
void main () {
var a = Vec3.from_data (4.0f, 5.0f, 6.0f);
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
var b = Vec3.from_data (1.0f, 2.0f, 3.0f);
stdout.printf ("Vec3 b x:%f y:%f z:%f\n", b.x, b.y, b.z);
stdout.printf("\n");
float s = a.dot_product (ref b);
// s = a.x*b.x + a.y*b.y + a.z*b.z
stdout.printf("s: %f\n", s);
stdout.printf("\n");
Vec3 c = a.cross_product (ref b);
// c.x = a.y*b.z - a.z*b.y, c.y = a.z*b.x - a.x*b.z, c.z = a.x*b.y - a.y*b.x
stdout.printf ("Vec3 c x:%f y:%f z:%f\n", c.x, c.y, c.z);
stdout.printf("\n");
a.mul (2);
// a.x = a.x * 2, a.y = a.y * 2, a.z = a.z * 2
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
a.div (2);
// a.x = a.x / 2, a.y = a.y / 2, a.z = a.z / 2
stdout.printf ("Vec3 a x:%f y:%f z:%f\n", a.x, a.y, a.z);
stdout.printf("\n");
float b_norm = b.norm ();
// b_norm = SQRT( b.x*b.x + b.y*b.y + b.z*b.z)
stdout.printf ("norm b : %f\n", b_norm);
stdout.printf("\n");
b.normalize ();
// b.x = b.x / b.norm(), b.y = b.y / b.norm(), b.z = b.z / b.norm()
stdout.printf ("b x:%f y:%f z:%f\n", b.x, b.y, b.z);
stdout.printf ("b norm = %f\n", b.norm());
stdout.printf("\n");
}
実行結果
Vec3 a x:4.000000 y:5.000000 z:6.000000
Vec3 b x:1.000000 y:2.000000 z:3.000000
s: 32.000000
Vec3 c x:3.000000 y:-6.000000 z:3.000000
Vec3 a x:8.000000 y:10.000000 z:12.000000
Vec3 a x:4.000000 y:5.000000 z:6.000000
norm b : 3.741657
b x:0.267261 y:0.534522 z:0.801784
b norm = 1.000000
*ビルド
valac --vapidir=./ --pkg glepoxy -X -lm prog1.vala MatrixMath.vala
( glepoxy.vapi も必要)
ValaGL + Gtk.GLArea ( Vala & OpenGL)
実行結果
(実際の実行では、スペースキーで、cubeが回転、停止します。)
下記のサイトで、Vala, SDL, GLEW で記述された、OpenGL 3.x に対応したrotating cubeアプリケーションが紹介されています。
(30/03/2013) ValaGL(simple skeletal application)
(https://github.com/lucidfox/valagl)
lucidfox | Vala and Modern OpenGL
http://lucidfox.dreamwidth.org/11614.html
http://en.lucidfox.org/2013/03/vala-and-modern-opengl/
1 GL 3.x APIに対応した vapiの作成
2 vec3とvec4に対応したmatrix とvector algebra、またprojections(camera)、
model matrix transformationsのVala言語による再実装
がなされています。
今回は、これらのプログラムを用いて、Gtk.GLArea上に同じrotating cubeを描画
します。
使用するプログラム
1 vapi
GLAreaでは、GLライブラリとしてepoxyを用いています。これに対応するように、
ここでは、CヘッダーファイルをGL/glew.hからepoxy/gl.hに変更しています。
(glepoxy.vapi)
2 ValaGL.Core内のプログラム
(GLProgram.vala、VBO.vala、IBO.vala、CoreError.vala、Camera.vala、
MatrixMath.vala、GeometryUtils.vala)
(1) VBO.vala、CoreError.vala、Camera.vala、MatrixMath.vala、GeometryUtils.vala
は変更なしで使用します。
(2) IBO.vala
1行コメントアウトします。
52行目 //glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0);
(3) GLProgram.vala
変更します。下記参照。
3 main.vala (App.valaに相当)
## main.vala
using Gtk;
using Gdk;
public class MainWindow : Gtk.Window
{
private glArea gl_area;
private float angle = 0.0f;
private uint tick_id;
private bool isRunning = false;
public MainWindow ()
{
title = "GLArea Test";
destroy.connect (Gtk.main_quit);
set_events (EventMask.KEY_PRESS_MASK );
var box = new Box (Orientation.VERTICAL, 0);
gl_area = new glArea ();
this.key_press_event.connect ((evt) => {
if (evt.keyval == Gdk.Key.space) {
GLib.message ("Key Pressed");
if (isRunning == false) {
tick_id = gl_area.add_tick_callback (tick);
} else {
gl_area.remove_tick_callback (tick_id);
}
isRunning = !isRunning;
}
return true;
});
var button = new Button.with_label ("Quit");
button.clicked.connect (Gtk.main_quit);
box.pack_start (gl_area, true, true);
box.pack_start (button, false, false);
add (box);
}
private bool tick (Widget widget, FrameClock frame_clock)
{
angle = angle + 1.0f;
stdout.printf("angle: %f\n", angle);
gl_area.update_scene_data(angle);
gl_area.queue_render ();
return true;
}
}
int main (string args)
{
Gtk.init (ref args);
var mainWindow = new MainWindow();
mainWindow.show_all ();
Gtk.main ();
return 0;
}
4 glArea.vala (Canvas.valaに相当)
## glArea.vala
using Gtk;
using Gdk;
using GL;
using ValaGL.Core;
public class glArea : Gtk.GLArea
{
private GLuint vao = {0};
private GLProgram gl_program;
private VBO coord_vbo;
private VBO color_vbo;
private IBO element_ibo;
private GLint mvp_location;
private float rotation_angle;
private GLfloat cube_vertices = {
// front
-1, -1, 1,
1, -1, 1,
1, 1, 1,
-1, 1, 1,
// back
-1, -1, -1,
1, -1, -1,
1, 1, -1,
-1, 1, -1
};
private GLfloat cube_colors = {
// front colors
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1,
// back colors
1, 0, 0,
0, 1, 0,
0, 0, 1,
1, 1, 1
};
private GLushort cube_elements = {
// front
0, 1, 2,
2, 3, 0,
// top
1, 5, 6,
6, 2, 1,
// back
7, 6, 5,
5, 4, 7,
// bottom
4, 0, 3,
3, 7, 4,
// left
4, 5, 1,
1, 0, 4,
// right
3, 2, 6,
6, 7, 3
};
public glArea ()
{
set_size_request (500, 400);
has_depth_buffer = true;
render.connect (on_render);
}
private bool on_render (GLContext contxt)
{
stdout.printf ("render\n");
// realize
glGenVertexArrays(1, vao);
glBindVertexArray(vao[0]);
try {
gl_program = new GLProgram();
coord_vbo = new VBO(cube_vertices);
color_vbo = new VBO(cube_colors);
element_ibo = new IBO(cube_elements);
} catch (CoreError e) {
stdout.printf("CoreError: %s\n", e.message);
}
mvp_location = gl_program.get_uniform_location("MVP");
glEnableVertexAttribArray(0);
coord_vbo.apply_as_vertex_array(0, 3);
glEnableVertexAttribArray(1);
color_vbo.apply_as_vertex_array(1, 3);
glBindVertexArray(0);
// render
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
var camera = new Camera ();
camera.set_perspective_projection (70.0f, 5.0f/4.0f, 0.01f, 100.0f);
var eye = Vec3.from_data (0, 2, 0);
var center = Vec3.from_data (0, 0, -2);
var up = Vec3.from_data (0, 1, 0);
camera.look_at (ref eye, ref center, ref up);
var model_matrix = Mat4.identity ();
Vec3 translation = Vec3.from_data (0, 0, -4);
GeometryUtil.translate (ref model_matrix, ref translation);
Vec3 rotation = Vec3.from_data (0, 1, 0);
GeometryUtil.rotate (ref model_matrix, rotation_angle, ref rotation);
gl_program.make_current();
camera.apply (mvp_location, ref model_matrix);
glBindVertexArray(vao[0]);
glDrawElements((GLenum)GL_TRIANGLES, cube_elements.length,
GL_UNSIGNED_SHORT, null);
glBindVertexArray (0);
glUseProgram (0);
glFlush();
return true;
}
public void update_scene_data (float angle)
{
rotation_angle = angle;
}
}
* depth_bufferを有効にするには、GLAreaクラスのプロパティhas_depth_bufferを
trueにします。
5 GLProgram.vala
vertex shaderとfragment shaderをここに記述します。これは、前回(2015/11/15)
説明したワーニングが出ないようにするためです。各shaderプログラムを直接glShaderSource()に渡します。
(1) shaderプログラムをクラス定義(public class GLProgram)の前に挿入します。
・## vertex shader
const string vert_src = {
"#version 330 core\n" +
"layout(location = 0) in vec3 coord3d;\n" +
"layout(location = 1) in vec3 v_color;\n" +
"out vec3 f_color;\n" +
"uniform mat4 MVP;\n" +
"void main() {\n" +
" f_color = v_color;\n" +
" gl_Position = MVP * vec4(coord3d, 1.0);\n" +
"}"};
・## fragment shader
const string[] frag_src = {
"#version 330 core\n" +
"in vec3 f_color;\n" +
"void main() {\n" +
" gl_FragColor = vec4(f_color.x, f_color.y, f_color.z, 1.0);\n" +
"}"};
(2) shaderプログラムが関連する引数を削除し、変更します。
・ public GLProgram () throws CoreError
・ vertex_shader = create_shader (GL_VERTEX_SHADER)
fragment_shaderも同様。
(3) shaderプログラムの読込み部分を変更します。
・ create_shader_from_file メソッドは使用しない。
・ private static Gluint create_shader (Gluint shader_type) throws CoreErroe
・ if (shader_type == GL_VERTEX_SHADER) {
glShaderSource (shader, 1, vert_src, null);
} else {
glShaderSource (shader, 1, frag_src, null);
}
* プログラム
ValaGL-GLArea.zip (http://yahoo.jp/box/PhHb1j )
* ビルド
valac --vapidir=./ --pkg gtk+-3.0 --pkg gdk-pixbuf-2.0 --pkg glepoxy -X -lepoxy -X -lm
main.vala glArea.vala Camera.vala MatrixMath.vala GeometryUtil.vala GLProgram.vala
VBO.vala IBO.vala CoreError.vala
Genie + OpenGL(3)
前回プログラム(Genie + OpenGL)のワーニング
前回使用したプログラム(testglarea.gsとglarea.gs)とvapiでは、glShaderSource関数に関して、以下のようなワーニングが出ていました。
** ワーニング **
testglarea.vala.c: 関数 ‘main_window_on_realize’ 内:
testglarea.vala.c:150:39: 警告: 互換性のないポインタ型から 3 番目の ‘epoxy_glShaderSource’ の引数に渡しています [-Wincompatible-pointer-types]
glShaderSource (_tmp3_, (GLsizei) 1, &vert_src, NULL);
^
testglarea.vala.c:150:39: 備考: expected ‘const GLchar * const* {aka const char * const*}’ but argument is of type ‘GLchar ** {aka char **}’
(vertex shaderとfragment shaderの両方で出てきます。)
関連するプログラムとvapiの部分は以下のようになっています。
プログラム
vert_src : GLchar* = "#version 330\n \n in vec4 position;\n void main() {\n gl_Position = position;\n }";
glShaderSource(vert_shader, 1, &vert_src, null);
(vert_src変数はポインターとして扱っています。)
vapi
public void glShaderSource (GLuint shader, GLsizei count, GLchar* *source, GLint* length);
今回、この部分をワーニングが出ないように修正しました。
プログラム
const vert_src : array of string = {"#version 330\n \n in vec4 position;\n void main() {\n gl_Position = position;\n }"};
glShaderSource(vert_shader, 1, vert_src, null);
vapi
public void glShaderSource (GLuint shader, GLsizei count, string *source, GLint* length);
##testglarea.gs
uses
GL
init
Gtk.init (ref args)
var mainWindow = new MainWindow()
mainWindow.show_all ()
Gtk.main ()
const vert_src : array of string = {"#version 330\n \n in vec4 position;\n void main() {\n gl_Position = position;\n }"};
const frag_src : array of string = {"#version 330\n \n out vec4 outputColor;\n void main() {\n outputColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n }"};
class MainWindow : Window
gl_vao : GLuint = 0
gl_program : GLuint
init
title = "GLArea Test"
destroy.connect (Gtk.main_quit)
var box = new Box (Orientation.VERTICAL, 0)
var glarea = new GLArea ()
glarea.set_size_request (500, 400)
glarea.render.connect (on_glarea_render)
var button = new Button.with_label ("Quit")
button.clicked.connect (Gtk.main_quit)
box.pack_start (glarea, true, true)
box.pack_start (button, false, false)
add (box)
def on_realize (cntxt:Gdk.GLContext)
print ("realize")
gl_buffer : GLuint = 0
/// 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);
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);
glUseProgram(gl_program);
glBindVertexArray(gl_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray (0);
glUseProgram (0);
glFlush();
return true
Genie + OpenGL(Gtk.GLArea)2
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”のオプションを入れています。
Genie + OpenGL(Gtk.GLArea)
gtk+-3.16から、Gtk.GLArea ウィジェが追加され、GtkWindow内で簡単にOpenGLプログラミングが出来るようになりました。OpenGL context等が自動的に設定されます。
OpenGLライブラリとして、epoxyライブラリを使用しています。
Gtk.GLArea ウィジェ とOpenGLを使って、三角形を描画しています。
Genie言語で記述しています。
vapiはgles2.vapiを参考に、epoxyライブラリで使用できるように追加・修正をしています。
glShaderSource()関数で、シェーダーファイルの指定が上手く処理できていません。
ポインターを使って記述しています。(ワーニングが出ます。)
##testglarea.gs
uses
GL
init
Gtk.init (ref args)
var mainWindow = new MainWindow()
mainWindow.show_all ()
Gtk.main ()
class MainWindow : Window
gl_vao : GLuint = 0
gl_program : GLuint
init
title = "GLArea Test"
destroy.connect (Gtk.main_quit)
var box = new Box (Orientation.VERTICAL, 0)
var glarea = new GLArea ()
glarea.set_size_request (500, 400)
glarea.render.connect (on_glarea_render)
var button = new Button.with_label ("Quit")
button.clicked.connect (Gtk.main_quit)
box.pack_start (glarea, true, true)
box.pack_start (button, false, false)
add (box)
def on_realize (cntxt:Gdk.GLContext)
print ("realize")
gl_buffer : GLuint = 0
vert_src : GLchar* = "#version 330\n \n in vec4 position;\n void main() {\n gl_Position = 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);
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);
glUseProgram(gl_program);
glBindVertexArray(gl_vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray (0);
glUseProgram (0);
glFlush();
return true
ビルド
valac --vapidir=../vapi --pkg gtk+-3.0 --pkg glepoxy -X -lepoxy testglarea.gs