Vala プログラミング

Rust & Vala プログラミング

おながのブログ

Rust glium テッセレーション ( Tessellation )

glium (https://github.com/tomaka/glium)のexamplesに、tessellationの
サンプル(tessellation.rs)があります。
上矢印キーと下矢印キーを使って、tessellation レベルを上げ下げできます。

実行結果
f:id:onagat12:20170424014421p:plain tessellation level = 2
f:id:onagat12:20170424014432p:plain tessellation level = 4
f:id:onagat12:20170424014438p:plain tessellation level = 8
(Inner-levelとOuter-levelは同じ値にしています。)

ビルドと実行
gliumフォルダで
$ cargo run --example tessellation
を実行します。

Rust ImGui + Glium ( OpenGL )

ImGui のGUI(ボタン)から、Gliumで描画したtriangleの回転角をコントロールできる
ようにしています。
f:id:onagat12:20170325183824g:plain
(実行結果)
・ imgui ウィンドウ上の「+」ボタンと「ー」ボタンを押すと、回転角の値が増減します。

プログラム
### imgui-glium.rs

#[macro_use]
extern crate glium;
#[macro_use]
extern crate imgui;

use glium::glutin;
use glium::glutin::{ElementState, Event, MouseButton, MouseScrollDelta, TouchPhase};
use glium::{DisplayBuild, Surface};
use imgui::{ImGui, ImGuiSetCond_FirstUseEver};
use imgui::glium_renderer::Renderer;
use std::time::Instant;

fn main() {
    let display = glutin::WindowBuilder::new()
        .with_dimensions(600, 600)
        .with_title(format!("ImGui Glium Test"))
        .build_glium().unwrap();

    let mut imgui = ImGui::init();
    let mut renderer = Renderer::init(&mut imgui, &display).unwrap();

    let mut last_frame = Instant::now();
    let mut mouse_pos = (0, 0);
    let mut mouse_pressed = (false, false, false);
    let mut mouse_wheel = 0.0;

   #[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];

    let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
    let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);

    let vertex_shader_src = r#"
        #version 140

        in vec2 position;

	uniform mat4 MVP;

        void main() {
            gl_Position = MVP * 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);
        }
    "#;

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

    let mut t: f32 = 0.0;

    loop {
        let mut target = display.draw();
        target.clear_color(0.2, 0.2, 0.2, 1.0);

        let uniform = uniform! {
	    MVP: [
	        [ t.cos(), t.sin(), 0.0, 0.0],
		[-t.sin(), t.cos(), 0.0, 0.0],
		[     0.0,     0.0, 1.0, 0.0],
		[     0.0,     0.0, 0.0, 1.0f32],
	    ],
	};
	target.draw(&vertex_buffer, &indices, &program, &uniform, &Default::default()).unwrap();

	let now = Instant::now();
	let delta = now - last_frame;
	let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0;
	last_frame = now;

	let scale = imgui.display_framebuffer_scale();
	imgui.set_mouse_pos(mouse_pos.0 as f32 / scale.0, mouse_pos.1 as f32 / scale.1);
	imgui.set_mouse_down(&[mouse_pressed.0, mouse_pressed.1, mouse_pressed.2, false, false]);
	imgui.set_mouse_wheel(mouse_wheel / scale.1);
	mouse_wheel = 0.0;

	let window = display.get_window().unwrap();
	let size_points = window.get_inner_size_points().unwrap();
	let size_pixels = window.get_inner_size_pixels().unwrap();

	let ui = imgui.frame(size_points, size_pixels, delta_s);

        // imgui ui
	ui.window(im_str!("Triangle"))
	    .position((10.0, 10.0), ImGuiSetCond_FirstUseEver)
	    .size((200.0, 100.0), ImGuiSetCond_FirstUseEver)
	    .build(|| {
                ui.text(im_str!("rotation"));
           	ui.separator();
		if ui.small_button(im_str!("+")) {
		    t += 0.02;
		}
		if ui.small_button(im_str!("-")) {
		    t -= 0.02;
		}
                ui.text(im_str!("rotation angle: {:.2} rad", t));
            });

	renderer.render(&mut target, ui).unwrap();
	target.finish().unwrap();

	for event in display.poll_events() {
	    match event {
	        Event::Closed => return,
		Event::MouseMoved(x, y) => mouse_pos = (x, y),
		Event::MouseInput(state, MouseButton::Left) =>
		    mouse_pressed.0 = state == ElementState::Pressed,
		Event::MouseInput(state, MouseButton::Right) =>
		    mouse_pressed.1 = state == ElementState::Pressed,
		Event::MouseInput(state, MouseButton::Middle) =>
		    mouse_pressed.2 = state == ElementState::Pressed,
		Event::MouseWheel(MouseScrollDelta::LineDelta(_, y), TouchPhase::Moved) =>
		    mouse_wheel = y,
		Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y), TouchPhase::Moved) =>
		    mouse_wheel = y,
		_ => ()
	    }
	}
    }
}

### Cargo.toml

[package]
name = "test1"
version = "0.1.0"
authors = ["xxxxx"]

[dependencies]
glium = "*"
imgui = "*"
image = "*"

Rust Glium CubeMap ( OpenGL )

CubeMap

f:id:onagat12:20170325185047g:plain
(実行結果)
・ cubemap 画像は、Humus サイト(http://www.humus.name/)のTexures(Yokohama 3)
 を使用しています。(画像サイズを512x512にしています。)


プログラム
###glium-cubemap.rs

#[macro_use]
extern crate glium;
extern crate image;

use std::io::Cursor;
use glium::{DisplayBuild, Surface};
use glium::glutin;
use glium::index::PrimitiveType;

mod camera;

fn main() {
    let display = glutin::WindowBuilder::new()
        .with_vsync()
        .with_depth_buffer(24)
        .with_dimensions(800, 600)
	.with_title(format!("Glium CubeMap"))
        .build_glium()
        .unwrap();


    let image = image::load(Cursor::new(&include_bytes!("images/posx512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_posx = glium::Texture2d::new(&display, image).unwrap();

    let image = image::load(Cursor::new(&include_bytes!("images/negx512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_negx = glium::Texture2d::new(&display, image).unwrap();

    let image = image::load(Cursor::new(&include_bytes!("images/posy512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_posy = glium::Texture2d::new(&display, image).unwrap();

    let image = image::load(Cursor::new(&include_bytes!("images/negy512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_negy = glium::Texture2d::new(&display, image).unwrap();

    let image = image::load(Cursor::new(&include_bytes!("images/posz512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_posz = glium::Texture2d::new(&display, image).unwrap();

    let image = image::load(Cursor::new(&include_bytes!("images/negz512.jpg")[..]),
                        image::JPEG).unwrap().to_rgba();
    let image_dimensions = image.dimensions();
    let image = glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), image_dimensions);
    let tex_negz = glium::Texture2d::new(&display, image).unwrap();

    let cubemap = glium::texture::Cubemap::empty(&display, 512).unwrap();

    // skybox
    let skybox_vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 3],
        }

        implement_vertex!(Vertex, position);

        let side2: f32 = 50.0 / 2.0;

        glium::VertexBuffer::new(&display,
            &[
                // Front
    		Vertex { position: [-side2, -side2,  side2] },
    		Vertex { position: [ side2, -side2,  side2] },
    		Vertex { position: [ side2,  side2,  side2] },
                Vertex { position: [-side2,  side2,  side2] },
    		// Right
    		Vertex { position: [ side2, -side2,  side2] },
    		Vertex { position: [ side2, -side2, -side2] },
    		Vertex { position: [ side2,  side2, -side2] },
                Vertex { position: [ side2,  side2,  side2] },
    		// Back
    		Vertex { position: [-side2, -side2, -side2] },
    		Vertex { position: [-side2,  side2, -side2] },
    		Vertex { position: [ side2,  side2, -side2] },
                Vertex { position: [ side2, -side2, -side2] },
    		// Left
    		Vertex { position: [-side2, -side2,  side2] },
    		Vertex { position: [-side2,  side2,  side2] },
                Vertex { position: [-side2,  side2, -side2] },
                Vertex { position: [-side2, -side2, -side2] },
                // Bottom
    		Vertex { position: [-side2, -side2,  side2] },
    		Vertex { position: [-side2, -side2, -side2] },
    		Vertex { position: [ side2, -side2, -side2] },
                Vertex { position: [ side2, -side2,  side2] },
    		// Top
                Vertex { position: [-side2,  side2,  side2] },
    		Vertex { position: [ side2,  side2,  side2] },
    		Vertex { position: [ side2,  side2, -side2] },
                Vertex { position: [-side2,  side2, -side2] },
    	    ]
        ).unwrap()
    };

    let skybox_index_buffer = glium::IndexBuffer::new(&display,
            glium::index::PrimitiveType::TrianglesList,
            &[
                // Front
                0u16, 2, 1, 0, 3, 2,
                // Right
                4, 6, 5, 4, 7, 6,
                // Back
                8, 10, 9, 8, 11, 10,
                // Left
                12, 14, 13, 12, 15, 14,
                // Bottom
                16, 18, 17, 16, 19, 18,
                // Top
                20, 22, 21, 20, 23, 22,
            ]).unwrap();

    let skybox_program = glium::Program::from_source(&display,
        " #version 140

            in vec3 position;
            out vec3 ReflectDir;

            uniform mat4 model;
            uniform mat4 view;
            uniform mat4 perspective;

            void main() {
                ReflectDir = position;
                gl_Position = perspective * view * model * vec4(position, 1.0);
            }
        ",
        " #version 140
            in vec3 ReflectDir;
            out vec4 color;

            uniform samplerCube cubetex;

            void main() {
                color = texture(cubetex, ReflectDir);
            }
        ",
        None).unwrap();

    //model
    let model_vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 3],
            normal:  [f32; 3],
        }

        implement_vertex!(Vertex, position, normal);

        let side2: f32 = 2.0 / 2.0;

        glium::VertexBuffer::new(&display,
            &[
                // Front
    		Vertex { position: [-side2, -side2,  side2], normal: [ 0.0,  0.0,  1.0] },
    		Vertex { position: [ side2, -side2,  side2], normal: [ 0.0,  0.0,  1.0] },
    		Vertex { position: [ side2,  side2,  side2], normal: [ 0.0,  0.0,  1.0] },
                Vertex { position: [-side2,  side2,  side2], normal: [ 0.0,  0.0,  1.0] },
    		// Right
    		Vertex { position: [ side2, -side2,  side2], normal: [ 1.0,  0.0,  0.0] },
    		Vertex { position: [ side2, -side2, -side2], normal: [ 1.0,  0.0,  0.0] },
    		Vertex { position: [ side2,  side2, -side2], normal: [ 1.0,  0.0,  0.0] },
                Vertex { position: [ side2,  side2,  side2], normal: [ 1.0,  0.0,  0.0] },
    		// Back
    		Vertex { position: [-side2, -side2, -side2], normal: [ 0.0,  0.0, -1.0] },
    		Vertex { position: [-side2,  side2, -side2], normal: [ 0.0,  0.0, -1.0] },
    		Vertex { position: [ side2,  side2, -side2], normal: [ 0.0,  0.0, -1.0] },
                Vertex { position: [ side2, -side2, -side2], normal: [ 0.0,  0.0, -1.0] },
    		// Left
    		Vertex { position: [-side2, -side2,  side2], normal: [-1.0,  0.0,  0.0] },
    		Vertex { position: [-side2,  side2,  side2], normal: [-1.0,  0.0,  0.0] },
                Vertex { position: [-side2,  side2, -side2], normal: [-1.0,  0.0,  0.0] },
                Vertex { position: [-side2, -side2, -side2], normal: [-1.0,  0.0,  0.0] },
                // Bottom
    		Vertex { position: [-side2, -side2,  side2], normal: [ 0.0, -1.0,  0.0] },
    		Vertex { position: [-side2, -side2, -side2], normal: [ 0.0, -1.0,  0.0] },
    		Vertex { position: [ side2, -side2, -side2], normal: [ 0.0, -1.0,  0.0] },
                Vertex { position: [ side2, -side2,  side2], normal: [ 0.0, -1.0,  0.0] },
    		// Top
                Vertex { position: [-side2,  side2,  side2], normal: [ 0.0,  1.0,  0.0] },
    		Vertex { position: [ side2,  side2,  side2], normal: [ 0.0,  1.0,  0.0] },
    		Vertex { position: [ side2,  side2, -side2], normal: [ 0.0,  1.0,  0.0] },
                Vertex { position: [-side2,  side2, -side2], normal: [ 0.0,  1.0,  0.0] },
    		]
        ).unwrap()
    };

    let model_index_buffer = glium::IndexBuffer::new(&display,
            glium::index::PrimitiveType::TrianglesList,
            &[
                // Front
                0u16, 2, 1, 0, 3, 2,
                // Right
                4, 6, 5, 4, 7, 6,
                // Back
                8, 10, 9, 8, 11, 10,
                // Left
                12, 14, 13, 12, 15, 14,
                // Bottom
                16, 18, 17, 16, 19, 18,
                // Top
                20, 22, 21, 20, 23, 22,
            ]).unwrap();

    let model_program = glium::Program::from_source(&display,
        " #version 140

            in vec3 position;
            in vec3 normal;
            out vec4 v_position;
            out vec3 v_normal;

            uniform mat4 model;
            uniform mat4 view;
            uniform mat4 perspective;

            void main() {
                mat4 modelviewMatrix = view * model;
                mat3 normalMatrix = mat3(modelviewMatrix);

                v_position = modelviewMatrix * vec4(position, 1.0);
                v_normal = normalMatrix * normal;
                gl_Position = perspective * v_position;
            }
        ",
        " #version 140
            in vec4 v_position;
            in vec3 v_normal;
            out vec4 f_color;

            uniform samplerCube cubetex;
            uniform float ReflectFactor;
            uniform vec4 MaterialColor;
            uniform vec3 WorldCameraPosition;

            void main() {
                vec3 s = normalize(v_normal);
                vec3 v = normalize(WorldCameraPosition - v_position.xyz);
                vec3 ReflectDir = reflect(v, s);
                vec4 cubeMapColor = texture(cubetex, ReflectDir);
                f_color = mix(MaterialColor, cubeMapColor, ReflectFactor);
            }
        ",
        None).unwrap();

    let dest_rect1 = glium::BlitTarget {
        left: 0,
        bottom: 0,
        width: 512,
        height: 512,
    };

    let mut camera = camera::CameraState::new();

    let scale: f32 = 1.0;
    let scale2: f32 = 1.0;
    let mut t: f32 = 0.0;

    // main loop
    loop {
	t += 0.002;

        let  framebuffer1 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::PositiveX)).unwrap();
        let  framebuffer2 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::NegativeX)).unwrap();
        let  framebuffer3 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::PositiveY)).unwrap();
        let  framebuffer4 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::NegativeY)).unwrap();
        let  framebuffer5 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::PositiveZ)).unwrap();
        let  framebuffer6 = glium::framebuffer::SimpleFrameBuffer::new(&display,
                        cubemap.main_level().image(glium::texture::CubeLayer::NegativeZ)).unwrap();

        tex_posx.as_surface().blit_whole_color_to(&framebuffer1, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);
        tex_negx.as_surface().blit_whole_color_to(&framebuffer2, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);
        tex_negy.as_surface().blit_whole_color_to(&framebuffer3, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);
        tex_posy.as_surface().blit_whole_color_to(&framebuffer4, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);
        tex_posz.as_surface().blit_whole_color_to(&framebuffer5, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);
        tex_negz.as_surface().blit_whole_color_to(&framebuffer6, &dest_rect1,
                        glium::uniforms::MagnifySamplerFilter::Linear);

        let mut target = display.draw();
        target.clear_color_and_depth((0.0, 0.0, 1.0, 1.0), 1.0);

        let model = [
        	[ t.cos()*scale,      0.0 , t.sin()*scale, 0.0],
        	[          0.0 , 1.0*scale,           0.0, 0.0],
        	[-t.sin()*scale,      0.0 , t.cos()*scale, 0.0],
        	[           0.0,      0.0 ,           0.0, 1.0f32],
        ];

        let camera_position: [f32; 3]= [0.0, 0.0, -8.0];
        camera.set_position((0.0, 0.0, -8.0));
        camera.set_direction((0.0, 0.0, 1.0));
        let view = camera.get_view();
        let perspective = camera.get_perspective();

        let material_color: [f32; 4] = [0.9, 0.9, 0.9, 1.0];
        let reflect_factor: f32 = 0.9;

        let skybox_uniforms = uniform! {
             model: model,
             view: view,
             perspective: perspective,
	     cubetex: cubemap.sampled().magnify_filter(glium::uniforms::MagnifySamplerFilter::Linear),
        };

        let model_uniforms = uniform! {
    	     model: [
                  [ t.cos()*scale2,       0.0 , t.sin()*scale2, 0.0],
                  [            0.0, 1.0*scale2,            0.0, 0.0],
                  [-t.sin()*scale2,       0.0 , t.cos()*scale2, 0.0],
                  [            0.0,       0.0 ,            0.0, 1.0f32]
             ],
             view: view,
             perspective: perspective,
             cubetex: cubemap.sampled().magnify_filter(glium::uniforms::MagnifySamplerFilter::Linear),
             ReflectFactor: reflect_factor,
             MaterialColor: material_color,
             WorldCameraPosition: camera_position,
    	};

        let params = glium::DrawParameters {
            depth: glium::Depth {
                test: glium::draw_parameters::DepthTest::IfLess,
                write: true,
                .. Default::default()
            },
            .. Default::default()
        };

        target.draw(&skybox_vertex_buffer, &skybox_index_buffer, &skybox_program,
                    &skybox_uniforms, &params).unwrap();
        target.draw(&model_vertex_buffer, &model_index_buffer, &model_program,
                    &model_uniforms, &params).unwrap();

        target.finish().unwrap();

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

### camera.rs
glium ソース内のexamples/supportのcamera.rsを使用。

###Cargo.toml

[package]
name = "cubemap"
version = "0.1.0"
authors = ["xxxxx"]

[dependencies]
glium = "*"
image = "*"
glutin = "*"

Rust glium OpenGL ( triangle )

Rust言語のgliumライブラリ(OpenGLライブラリ)を用いて、coloured triangleを
描画しています。

f:id:onagat12:20170322155548g:plain

( 実行結果)
・triangleは、上矢印キー(左回転)と下矢印キー(右回転)を使って回転させて
 います。

プログラム
### triangle.rs
#[macro_use]
extern crate glium;

use glium::{DisplayBuild, Surface};
use glium::glutin;

fn main() {

    let display = glutin::WindowBuilder::new()
        .with_dimensions(600, 600)
        .with_title(format!("Glium Triangle Test"))
        .build_glium().unwrap();

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

  implement_vertex!(Vertex, position, color);
  let vertex1 = Vertex { position: [-0.5, -0.5], color: [0.0, 0.0, 1.0] };
  let vertex2 = Vertex { position: [ 0.0, 0.5], color: [0.0, 1.0, 0.0] };
  let vertex3 = Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] };
  let shape = vec![vertex1, vertex2, vertex3];
  let vertex_buffer = glium::VertexBuffer::new(&display, &shape).unwrap();
  let indices = glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList);
  let vertex_shader_src = r#"
      #version 140
    in vec2 position;
    in vec3 color;
    out vec3 vColor;

    uniform mat4 matrix;

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

  let fragment_shader_src = r#"
       #version 140
       in vec3 vColor;
       out vec4 f_color;
       void main() {
         f_color = vec4(vColor, 1.0);
       }
  "#;

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

  loop {
       let mut target = display.draw();
       target.clear_color(0.0, 0.0, 0.0, 1.0);
       let uniforms = uniform! {
         matrix: [
              [ t.cos(), t.sin(), 0.0, 0.0],
              [-t.sin(), t.cos(), 0.0, 0.0],
              [ 0.0, 0.0, 1.0, 0.0],
              [ 0.0, 0.0, 0.0, 1.0f32],
         ]
     };

    target.draw(&vertex_buffer, &indices, &program, &uniforms,
                       &Default::default()).unwrap();
    target.finish().unwrap();

    for ev in display.poll_events() {
         match ev {
              glium::glutin::Event::Closed => return,
              glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _,                                Some(glutin::VirtualKeyCode::Up)) => {
                        t += 0.01;
                        println!("KeyUP Pressed {}", t);
                    },
              glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _,
                   Some(glutin::VirtualKeyCode::Down)) => {
                      t -= 0.01;
                         println!("KeyDown Pressed {}", t);
            },
       _ => ()
               }
          }
     }
}

・gliumライブラリのexamplesの例を組み合わせています。


### Cargo.toml
[package]
name = "triangle"
version = "0.1.0"
authors = ["xxxxx"]

[dependencies]
glium = "*"

 

Elementary OS

f:id:onagat12:20170303232737p:plain

Elementary OS 0.4 (Loki)
https://elementary.io/ja/

Ubuntu 16.04 (LTS) をベースにしたデスクトップです。

Korora25

f:id:onagat12:20161105124845p:plain

Korora25
Korora Project

現在使用しているLinuxデスクトップです。
Fedora25(GNOME)相当で、Dash to Dock など幾つかのGNOME Shell 拡張等が前もってインストールされています。
使い易いデスクトップになっています。

Vala OpenGL ( ValaGL MatrixMath.vala )

ValaGL MatrixMath.vala の演算

Mat4 ( 4x4 行列)

Mat4 の定義
struct Mat4
   メンバー
   float data[16]
      Mat4 各要素
      m11(data[0]), m12(data[4]), m13(data[8]), m14(data[12])
      m21(data[1]), m22(data[5]), m23(data[9]), m24(data[13])
      m31(data[2]), m32(data[6]), m33(data[10]), m348data[14])
      m41(data[3]), m42(data[7]), m43(data[11]), m44(data[15])

   メソッド
   *生成
   Mat4()
      要素が 0 値の Mat4 を生成
      (Creates a new matrix, zero initialized.)
   Mat4.from_data (GLfloat a11, GLfloat a12, GLfloat a13, GLfloat a14,
                             GLfloat a21, GLfloat a22, GLfloat a23, GLfloat a24,
                             GLfloat a31, GLfloat a32, GLfloat a33, GLfloat a34,
                             GLfloat a41, GLfloat a42, GLfloat a43, GLfloat a44)
      要素が、以下のようになる Mat4 を生成
      m11 = a11, m12 = a12, m13 = a13, m14 = a14
      m21 = a21, m22 = a22, m23 = a23, m24 = a24
      m31 = a31, m32 = a32, m33 = a33, m34 = a34
      m41 = a41, m42 = a42, m43 = a43, m44 = a44
      (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).)
   Mat4.from_vec_mul (ref Vec4 a, ref Vec4 b)
      2つの Vec4 a, b から Mat4 を生成(a * bT の計算、bT は b の
      転置ベクトル)
      m11 = a.x * b.x, m12 = a.x * b.y, m13 = a.x * b.z, m14 = a.x * b.w
      m21 = a.y * b.x, m22 = a.y * b.y, m23 = a.y * b.z, m24 = a.y * b.w
      m31 = a.z * b.x, m32 = a.z * b.y, m33 = a.z * b.z, m34 = a.z * b.w
      m41 = a.w * b.x, m42 = a.w * b.y, m43 = a.w * b.z, m44 = a.w * b.w
      (Given two vectors ``a`` and ``b``, computes a matrix equal to
       ``a * bT``.)
   Mat4.from_array (GLfloat[] data)
      要素が配列 data で与えられる Mat4 を生成
      m11 = data[0], m12 = data[4], m13 = data[8], m14 = data[12]
      m21 = data[1], m22 = data[5], m23 = data[9], m24 = data[13]
      m31 = data[2], m32 = data[6], m33 = data[10], m34 = data[14]
      m41 = data[3], m42 = data[7], m43 = data[11], m44 = data[15]
      (Creates a matrix whose contents are the copy of the given
       array,assumed to have at least 16 elements.)
   Mat4.identity ()
      単位行列を生成
      m11 = 1, m12 = 0, m13 = 0, m14 = 0
      m21 = 0, m22 = 1, m23 = 0, m24 = 0
      m31 = 0, m32 = 0, m33 = 1, m34 = 0
      m41 = 0, m42 = 0, m43 = 0, m44 = 1
      (Creates an identity matrix.)
   Mat4.expand (ref Mat3 mat3)
      Mat3行列 mat3(A) を拡張して、Mat4行列を生成
      m11 = a11, m12 = a12, m13 = a13, m14 = 0
      m21 = a21, m22 = a22, m23 = a23, m24 = 0
      m31 = a31, m32 = a32, m33 = a33, m34 = 0
      m41 = 0, m42 = 0, m43 = 0, m44 = 1
      (Creates an expansion of the given 3x3 matrix into 4x4.)

  *ベクトル演算
   void add (ref Mat4 other)
      this(インスタンス)と other 行列との和(要素間の和)
      (Adds the given matrix, component-wise.)
   void sub (ref Mat4 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 Mat4 other)
      this(インスタンス、Mat4)と other 行列(Mat4)の積
    ( this × other )
      (Multiplies the given matrix using the linear algebra definition of
       matrix multiplication.)
   Vec4 mul_vec (ref Vec4 vec)
      this(インスタンス, Mat4)と vec ベクトル(Vec4) の積
      ( this × vec )
      (Multiplies this matrix by the given vector and returns the result
       as a new vector.)

   Mat4 transposed ()
      this(インスタンス, Mat4)の転置行列を生成
      (Returns a new matrix that is the transposition of this matrix.)
   GLfloat det ()
      this(インスタンス, Mat4)の行列式を計算
      (Computes the determinant of this matrix.)
   Mat4 inverted (out bool success)
      this(インスタンス, Mat4)の逆行列を生成
      逆行列が存在しない場合、success に "false" が設定される。
      逆行列が存在する場合、success に "true" が設定され、
      逆行列が生成される。
      (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 not successfully
            inverted, otherwise the return value is undefined.)

*Mat4 の生成・演算は、Mat3 とほぼ同様です。