Vala プログラミング

WebGPU プログラミング

おなが@京都先端科学大

Rust OpenGL gliumライブラリ

今回は、RustでOpenGLを扱うライブラリの一つであるgliumについて
まとめています。(glium([https://github.com/tomaka/glium/)
examplesにあるtutorial-02.rsを使用しています。)

gliumでは、OpenGLAPIとは異なる独自のAPIを導入しています。
以下は、gliumでOpenGLを描画する際必要となる文です。

1 windowとOpenGL contextの準備

use glium::{DisplayBuild, Surface};
let display = glium::glutin::WindowBuilder::new()
    .with_dimensions(800, 600)
    .with_title(format!("Glium Triangle Test"))
    .build_glium().unwrap();

window操作のライブラリとして、glutinを利用しています。
この文は、windowとOpenGL contextを生成します。その際、windowサイズ、
windowタイトルも設定しています。


2 vertexの設定

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 2],
}

implement_vertex!(Vertex, position);

let vertex1 = Vertex { position: [-0.5, -0.5] };
let vertex2 = Vertex { position: [ 0.0,  0.5] };
let vertex3 = Vertex { position: [ 0.5, -0.5] };
let shape = vec![vertex1, vertex2, vertex3];

#[derive]は継承のアトリビュートです。Vertex structureは、Copy, Clone
トレイトの機能を継承することになります。
頂点座標は、Vertex structureのベクトルとして設定します。


3 VertexBufferの設定

let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();

頂点座標を、VertexBufferに設定します。


4 IndexBufferの設定

let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

IndexBufferの設定に相当する文です。
この例では、indexを使用しません。このような場合は、primitive typeを
設定するため、NoIndicesを使います。


5 shaderの設定

let vertex_shader_src = r#"
    #version 140

    in vec2 position;

    void main() {
        gl_Position = vec4(position, 0.0, 1.0);
    }
"#;

let fragment_shader_src = r#"
    #version 140

    out vec4 color;

    void main() {
        color = vec4(1.0, 0.0, 0.0, 1.0);
    }
"#;


6 shderのリンク

let program = glium::Program::from_source(&display, vertex_shader_src,
    fragment_shader_src, None).unwrap();

shaderプログラムのリンクには、Program文を使用します。
最後の引数Noneは、geometry shaderを使用しないことを示しています。


7 windowのクリア、描画、終了

let mut target = display.draw();
    target.clear_color(0.0, 0.0, 1.0, 1.0);
    target.draw(&vertex_buffer, &indices, &program, &glium::uniforms::EmptyUniforms,
                &Default::default()).unwrap();
    target.finish().unwrap();

display.draw()で、描画用フレームバッファ(バックバッファ)を生成します。
target.draw()で、フレームバッファに描画します。その際、VertexBuffer, IndexBuffer,
Programを設定します。
この例では、uniform変数を使用していないので、EmptyUniformsを設定しています。
また、depth、stencil等の描画パラメータも使用していないので、DrawParametersの
設定にはDefaule::default()を設定しています。
target.finish()で、フロントバッファに描画します。


8 windowのクローズ

for ev in display.poll_events() {
    match ev {
        glium::glutin::Event::Closed => return,
        _ => ()
    }
}

display.poll_events()で、ウィンドウのイベントリストを生成します。
「glium::glutin::Event::Closed => return」文で、ウィンドウのClosedイベントを
検出するとreturn文を用いて、ループ(loop{})を抜けるようにしています。