【问题标题】:C# ModelViewMatrix implementation using Stack<Matrix4> vs. Uniform passing使用 Stack<Matrix4> 与统一传递的 C# ModelViewMatrix 实现
【发布时间】:2014-03-17 00:28:34
【问题描述】:

我正在尝试使用 OpenTK 将实现非固定管道矩阵的 C++ 代码重写为 C#。我遇到了问题,因为我不明白为什么这段代码无效。

static class ModelView
{
    static private Stack<Matrix4> matrix = new Stack<Matrix4>();
    static public Matrix4 Matrix
    {
        get
        {
            return matrix.Peek();
        }
        set
        {
            matrix.Pop();
            matrix.Push(value);
        }
    }
    static public Matrix4 MatrixNormal
    {
        get
        {
            Matrix4 m = matrix.Peek();
            m.Invert();
            m.Transpose();
            return m;
        }
    }
    static public int Uniform { get; set; }
    static public int UniformNormal { get; set; }

    static private void SetUniforms()
    {
        if (Uniform == -1 || UniformNormal == -1)
            throw new Exception("Projection matrix uniform is uninitialized");
        GL.UniformMatrix4(Uniform, false, ref Matrix);
        GL.UniformMatrix4(UniformNormal, false, ref MatrixNormal);            
    }

    /* stack & matrices manipulating funcs */
}

Visual Studio 说“不能将属性、索引器或动态成员访问作为 out 或 ref 参数传递。”在那些线上:

GL.UniformMatrix4(Uniform, false, ref Matrix);
GL.UniformMatrix4(UniformNormal, false, ref MatrixNormal);     

为什么我不能传递 Stack.Peek() 因为它应该只是对象引用。

【问题讨论】:

    标签: c# opengl opentk


    【解决方案1】:

    这是因为您的 Matrix 和 MatrixNormal 是属性,您不能将其作为 ref 参数发送,您需要为它们使用方法而不是属性

    当您/get/set 字段值是什么或它是一些轻量级函数时使用属性是一个好习惯,但您的情况最好在这里使用方法。 尝试这个: (将方法返回值作为字段)

    public class Matrix
    {
        private Stack<Matrix4> matrix = new Stack<Matrix4>();
        Matrix4 peek = null; 
        public Matrix4 Peek()
        {
            peek = matrix.Peek();
            return peek;
    
        }
    
        public void Peek(Matrix4 value)
        {
            matrix.Pop();
            matrix.Push(value);
    
        }
        private Matrix normalMatrix = null;
        public Matrix4 MatrixNormal()
        {
            Matrix4 m = matrix.Peek();
                m.Invert();
                m.Transpose();
                normalMatrix = m;
                return normalMatrix;
        }
        public int Uniform { get; set; }
        public int UniformNormal { get; set; }
    
         private void SetUniforms()
    
    
     {
            if (Uniform == -1 || UniformNormal == -1)
                throw new Exception("Projection matrix uniform is uninitialized");
            Peek();
            MatrixNormal();
            GL.UniformMatrix4(Uniform, false, ref peek);
    
            GL.UniformMatrix4(UniformNormal, false, ref normalMatrix);            
        }
    

    【讨论】:

    • 但错误在MatrixMatrixNormal。所以我必须创建自己的 getter 和 setter 函数并删除访问器?
    • 你为我清除了这个。我只需要知道 C# 做这类事情的方式。
    • 请注意 Matrix4 不是一个类,所以这一行不会编译:Matrix4 peek = null;。相反,使用Matrix4 peek = Matrix4.Identity;
    【解决方案2】:

    作为 ref 传递的参数可以被调用的方法读取和写入。一个 Property 就像一个具有 getter 和 setter 的对象(嗯,它不需要同时拥有),并且不能假设 getter 和 setter 具有相同的支持字段。因此,不可能/不允许将 Property 作为 ref 参数传递。

    【讨论】:

    • 那么正确和语义化的做法是像 C++ 中那样删除访问器和 crate 获取和设置函数?
    • yes 方法(函数)在您的情况下更好,但您仍然需要将方法结果复制到变量中,然后将其作为 ref 参数传递
    • 好吧,我不这么认为。在将MatrixMatrixNormal 用作参考参数之前,我只需创建一个新的引用即可。
    • Matrix4 m = 矩阵; Matrix4 mn = MatrixNormal; GL.UniformMatrix4(Uniform, false, ref m); GL.UniformMatrix4(UniformNormal, false, ref mn);这段代码行得通,但复制不是没用吗?
    • 是的,这是不必要的复制。根据我对您的代码的了解,matrix 堆栈永远不能包含超过一项。这个对吗?如果您只需要它的一个实例,为什么不创建一个私有字段作为属性的支持?
    【解决方案3】:

    问题在于,使用 ref 参数时,您必须提供在 C++ 中被视为指针的内容。一个属性是不行的,因为那只不过是一个带有一些语法糖的方法(或两个方法)。属性会给你价值,而不是内存地址。

    如果您不想(或不能)将矩阵作为 ref 参数传递,则必须使用不同的 GL.UniformMatrix4 重载,例如:

    GL.UniformMatrix4(int location, int count, bool transpose, float[] value)
    

    您只需将 Matrix4 对象转换为 16 个浮点数的数组。

    【讨论】:

    • 您不必从Matrix4 转换为float,您可以传递ref Matrix4.Row0.X,OpenTK 将固定并将整个矩阵传递给驱动程序。这是一个帮助您编写更快代码的小技巧。
    • @TheFiddler 这应该在 OpenTK 文档之类的。
    猜你喜欢
    • 2012-09-30
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多