简体   繁体   English

如何在glium中使用cgmath :: Matrix作为统一参数?

[英]How can I use a cgmath::Matrix as a uniform parameter in glium?

I'm trying to integrate the cgmath library into my first experiments with glium , but I can't figure out how to pass my Matrix4 object to the draw() call. 我正在尝试将cgmath库集成到我的第一个glium实验中,但我无法弄清楚如何将我的Matrix4对象传递给draw()调用。

My uniforms object is defined thus: 我的uniforms对象是这样定义的:

let uniforms = uniform! {
    matrix: cgmath::Matrix4::from_scale(0.1)
};

and this is my draw call: 这是我的draw电话:

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

which fails to compile with the message 无法使用该消息进行编译

error[E0277]: the trait bound `cgmath::Matrix4<{float}>: glium::uniforms::AsUniformValue` is not satisfied

I'm a total beginner with Rust, but I do believe I cannot implement this trait myself, as both it and the Matrix4 type are in a crate separate from mine. 我是Rust的初学者,但我确实认为自己无法实现这一特性,因为它和Matrix4类型都与我的分开。

Is there really no better option than to manually convert the matrix into an array of arrays of floats? 除了手动将矩阵转换为浮点数组数组之外,真的没有更好的选择吗?

I do believe I cannot implement this trait myself, as both it and the Matrix4 type are in a crate separate from mine. 我确实认为自己无法实现这一特性,因为它和Matrix4类型都与我的箱子分开。

This is very true. 这是非常正确的。

Is there really no better option than to manually convert the matrix into an array of arrays of floats? 除了手动将矩阵转换为浮点数组数组之外,真的没有更好的选择吗?

Well, you don't have to do a lot manually. 好吧,你不必手动做很多事情。

First, it's useful to note that Matrix4<S> implements Into<[[S; 4]; 4]> 首先,注意Matrix4<S> 实现Into<[[S; 4]; 4]> Into<[[S; 4]; 4]> Into<[[S; 4]; 4]> (I can't link to that impl directly, so you have to use ctrl + f ). Into<[[S; 4]; 4]> (我无法直接链接到那个impl,所以你必须使用ctrl + f )。 That means that you can easily convert a Matrix4 into an array which is accepted by glium. 这意味着您可以轻松地将Matrix4转换为Matrix4接受的数组。 Unfortunately, into() only works when the compiler knows exactly what type to convert to. 不幸的是, into()仅在编译器确切知道要转换为何种类型时才有效。 So here is a non-working and a working version: 所以这是一个非工作和工作版本:

// Not working, the macro accepts many types, so the compiler can't be sure 
let uniforms = uniform! {
    matrix: cgmath::Matrix4::from_scale(0.1).into()
};

// Works, because we excplicitly mention the type
let matrix: [[f64; 4]; 4] = cgmath::Matrix::from_scale(0.1).into();
let uniforms = uniform! {
    matrix: matrix,  
};

But this solution might be still too much to write. 但是这个解决方案可能仍然无法编写。 When I worked with cgmath and glium , I created a helper trait to reduce code size even more. 当我使用cgmathglium ,我创建了一个辅助特性来减少代码大小。 This might not be the best solution, but it works and has no obvious downsides (AFAIK). 这可能不是最好的解决方案,但它有效并且没有明显的缺点(AFAIK)。

pub trait ToArr {
    type Output;
    fn to_arr(&self) -> Self::Output;
}

impl<T: BaseNum> ToArr for Matrix4<T> {
    type Output = [[T; 4]; 4];
    fn to_arr(&self) -> Self::Output {
        (*self).into()
    }
}

I hope this code explains itself. 我希望这段代码能够解释自己。 With this trait, you now only have to use the trait near the draw() call and then: 有了这个特性,你现在只需要在draw()调用附近use特征,然后:

let uniforms = uniform! {
    matrix: cgmath::Matrix4::from_scale(0.1).to_arr(),
    //                                      ^^^^^^^^^
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM