原地址: github.com/glium/glium/

創建項目

首先, 創建一個新項目:

cargo new --bin my_project
cd my_project

在你剛創建的目錄下的 Cargo.toml 文件中含有項目的元數據, src/main.rs 文件包含了Rust的源代碼. 如果在目錄下的文件不是 src/main.rs 而是 src/lib.rs , 說明你忘了輸入 --bin 選項; 只要將 src/lib.rs 重命名為 src/main.rs 就可以了.

Cargo.toml 文件中添加如下依賴, 以在項目中導入glium庫:

[dependencies]
glium = "*"

在使用依賴庫之前, 需要在 src/main.rs 中添加如下代碼以導入庫:

#[macro_use]
extern crate glium;

fn main() {
}

是時候開始填滿 main 函數了!

創建窗口

創建圖形應用的第一步就是創建一個窗口. 如果你熟悉OpenGL那一套, 你應該瞭解其中的複雜程度. 無論是創建窗口還是創建上下文(Context), 在不同平臺下的你要寫的代碼是不一樣的, 唯一不變的是: 它非常無聊. 幸運的是, 這正是 glutin 庫所擅長的東西.

使用glutin初始化OpenGL窗口需要經過如下幾步:

  1. 創建 EventsLoop 用於處理窗口和設備的事件.
  2. 使用 glium::glutin::WindowBuilder::new() 指定窗口的參數. 這些參數與OpenGL無關, 而是窗口特有的屬性.
  3. 使用glium::glutin::ContextBuilder::new()指定上下文(Context)參數. 我們可以在這裡設置OpenGL特定的屬性, 例如垂直同步與多重採樣.
  4. 創建OpenGL窗口(在glium中稱為 Display): glium::Display::new(window, context, &events_loop).unwrap() 這句代碼使用給定的窗口和上下文創建了一個Dispaly, 並且使用所給的events_loop註冊窗口.

fn main() {
use glium::glutin;

let mut events_loop = glutin::EventsLoop::new();
let window = glutin::WindowBuilder::new();
let context = glutin::ContextBuilder::new();
let display = glium::Display::new(window, context, &events_loop).unwrap();
}

但是有一個問題: 在窗口創建完成時, 我們的main函數就退出了, 導致 display 的析構函數關閉了窗口. 為了避免這個問題, 我們需要創建一個無限循環, 直到收到 CloseRequested 事件為止:

let mut closed = false;
while !closed {
// 列出由應用生成的事件並等待接收
events_loop.poll_events(|ev| {
match ev {
glutin::Event::WindowEvent { event, .. } => match event {
glutin::WindowEvent::CloseRequested => closed = true,
_ => (),
},
_ => (),
}
});
}

雖然, 這段代碼將導致CPU佔用率達到100%, 但是已經解決了上面所說的問題. 在實際的應用程序中, 你應當使用垂直同步或者在每次循環結束時sleep幾毫秒, 不過這是之後要考慮的事了.

你現在可以運行 cargo run. 在Cargo下載完glium及其依賴並編譯好之後, 你就能看見一個還過得去的小窗口了.

清除顏色

然而, 窗口裡的內容並不怎麼吸引人. 它也許是一片空白, 或者是一張隨機的圖片, 也可能是一些雪花, 這取決於你使用什麼系統. 我們需要在窗口內繪製圖形, 因此係統並不需要將窗口內的顏色初始化為某個特定的值.

Glium和OpenGL的API就像Windows下的畫筆工具. 首先我們有一幅空白的畫布, 我們可以在上面畫一個又一個圖形. 到你覺得滿意為止. 和繪圖軟體不一樣的是, 你不想你的用戶看見繪畫的過程. 他們能看見的應該只有最終的結果.

glium使用 Frame 對象來實現這一機制. 如果你打算在窗口中繪製圖形, 首先應該調用 display.draw() 方法來創建一個 Frame:

let mut target = display.draw();

之後, 我們就能將 target 作為畫布(drawing surface). OpenGL和glium提供的一個操作就是使用給定的顏色填充畫布. 這正是我們要做的.

target.clear_color(0.0, 0.0, 1.0, 1.0);

注意: 我們需要先導入 Surface trait, 然後才能使用這個函數:

use glium::Surface;

我們傳遞給 clear_color 的四個值表示顏色的四個組成部分: 紅, 綠, 藍和透明度. 取值範圍為[0.0, 1.0]. 這裡我們選擇的是不透明的藍色.

正如我之前解釋的, 現在用戶沒法在屏幕上看見藍色. 如果我們是在寫一個真正的應用的話, 我們也許會畫上角色, 武器, 地面, 天空等等. 但是在這個指南中, 我們做到這一步就足夠了:

target.finish().unwrap();

finish() 函數意味著我們結束了繪製. 它將銷毀 Frame 對象, 並將畫布複製到窗口上. 現在, 我們的窗口被一片藍色填滿了.

以下是所有的代碼:

fn main() {
use glium::{glutin, Surface};

let mut events_loop = glium::glutin::EventsLoop::new();
let window = glium::glutin::WindowBuilder::new();
let context = glium::glutin::ContextBuilder::new();
let display = glium::Display::new(window, context, &events_loop).unwrap();

let mut closed = false;
while !closed {
let mut target = display.draw();
target.clear_color(0.0, 0.0, 1.0, 1.0);
target.finish().unwrap();

events_loop.poll_events(|ev| {
match ev {
glutin::Event::WindowEvent { event, .. } => match event {
glutin::WindowEvent::CloseRequested => closed = true,
_ => (),
},
_ => (),
}
});
}
}

推薦閱讀:

相關文章