Rust에서 OpenGL과 같은 그래픽 라이브러리를 활용하는 방법

개시하다


Rust에서 OpenGL, OpenGLES, EGL 등 도형 라이브러리(본가가 원래 C 언어의 라이브러리)를 사용하는 방법을 총결하였다.

Foreign Function Interface(ffi)의 문제점 활용


알다시피 Rust에서 다른 언어의 라이브러리를 사용할 때는 Foreign Function Interface(ffi)를 사용하여 바인딩해야 합니다.하지만 수량이 적고 자신이 만든 라이브러리라면 자신도 fi에 대응할 수 있지만 대기 대상의 수량이 많거나 자주 업데이트되는 라이브러리를 대상으로 하면 일이 힘들어진다.

gl_generator란?


OpenGL 등 도형 라이브러리의 귀속기중기가 여러 개 있지만 gl_generator 이 화산구가 가장 많이 쓰인다.또 모질라가 개발한 Firefox의 렌더링 엔진 Servo도 이 라이브러리servo / gleam를 사용했다.본가 모질라가 사용하는 프로그램 라이브러리라 신뢰도가 높죠?

gl_소스 코드 자동 생성 도구


gl_generator는 도형 라이브러리의 귀속 소스 코드가 아닌 귀속 소스 코드를 자동으로 생성하는 도구입니다.따라서 사용 방법은'구축 과정에서 자동으로 원본 코드를 생성하고 구축한다','glgenerator를 이용하여 원본 코드를 미리 생성하고 이용한다'는 두 가지 모델이 있다.이번에는 전자의 방법을 소개한다.

gl_generator 사용 방법


귀속 대상의 독립 기중기 만들기


이번에는 오픈지엘의 독자 크레인을 만드는 방법을 소개한다.

독립gl기중기의 제작


목표 프로젝트의 루트 디렉터리에서 다음 동작을 실행하여gl크레인 라이브러리를 만듭니다.
$ mkdir lib
$ cd lib
$ cargo new --vcs none --lib gl

lib/gl/src/build.문서 작성


이 소스 코드에 OpenGL의 바인딩 소스 코드를 자동으로 생성하는 코드를 씁니다.다음 코드를 써서 구축할 때 target 디렉터리 이하의 규정된 위치에서 파일을 생성합니다 gl_bindings.rs.
extern crate gl_generator;

use gl_generator::{Api, Fallbacks, Profile, Registry};
use std::env;
use std::fs::File;
use std::path::Path;

fn main() {
    // OpenGL 3.3 bindings
    let dest = env::var("OUT_DIR").unwrap();
    let mut file_gl = File::create(&Path::new(&dest).join("gl_bindings.rs")).unwrap();
    let gl_extensions = [
        "GL_APPLE_client_storage",
        "GL_APPLE_fence",
        "GL_APPLE_texture_range",
        "GL_APPLE_vertex_array_object",
        "GL_ARB_blend_func_extended",
        "GL_ARB_buffer_storage",
        "GL_ARB_copy_image",
        "GL_ARB_get_program_binary",
        "GL_ARB_invalidate_subdata",
        "GL_ARB_texture_rectangle",
        "GL_ARB_texture_storage",
        "GL_EXT_debug_marker",
        "GL_EXT_texture_filter_anisotropic",
        "GL_KHR_debug",
        "GL_KHR_blend_equation_advanced",
        "GL_KHR_blend_equation_advanced_coherent",
        "GL_KHR_blend_equation_advanced_coherent",
        "GL_ARB_shader_storage_buffer_object",
    ];
    let gl_reg = Registry::new(
        Api::Gl,
        (3, 3), // Open GL の対象バージョン
        Profile::Compatibility,
        Fallbacks::All,
        gl_extensions,
    );
    gl_reg
        .write_bindings(gl_generator::StructGenerator, &mut file_gl)
        .unwrap();
}

lib/gl/src/lib.rs의 수정


위에서 생성한 소스 코드gl_bindings.rs를 사용하도록 지정합니다.
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));

lib/gl/Cargo.toml 수정


gl_generator를 추가하여 스크립트 자동 생성(build.rs)을 지정합니다.
[package]
... (略)
build = "build.rs"

[build-dependencies]
gl_generator = "0.14.0"

프로젝트의 카고.toml에 추가


마지막으로 프로젝트 바로 아래의 Cargo.toml 파일에 혼자의gl크레인을 추가합니다.
[dependencies]
gl = { path = "lib/gl" }

구축


$ cargo build
에서 원본 코드를 자동으로 생성하여 구축할 수 있을 것입니다.

EGL 대상 시 고려 사항


EGL의 소스 코드를 생성하려면 대상 플랫폼 환경에 따라 몇 가지 유형을 정의해야 합니다.

예.lib/egl/src/lib.rs


#[allow(non_camel_case_types)]
mod egl {
    use std::os::raw::{c_long, c_void};
    use wayland_sys::client::wl_display;
    use wayland_sys::egl::wl_egl_window;

    pub type khronos_int32_t = i32;
    pub type khronos_ssize_t = c_long;
    pub type khronos_uint64_t = u64;
    pub type khronos_utime_nanoseconds_t = khronos_uint64_t;

    pub type EGLNativeDisplayType = *mut wl_display;
    pub type EGLNativePixmapType = *mut c_void;
    pub type EGLNativeWindowType = *mut wl_egl_window;
    pub type EGLint = khronos_int32_t;
    pub type NativeDisplayType = EGLNativeDisplayType;
    pub type NativePixmapType = EGLNativePixmapType;
    pub type NativeWindowType = EGLNativeWindowType;

    include!(concat!(env!("OUT_DIR"), "/egl_bindings.rs"));
}

좋은 웹페이지 즐겨찾기