使用Stack <matrix4>与Uniform传递</matrix4>的C#ModelViewMatrix实现

时间:2014-03-17 00:28:35

标签: c# opengl opentk

我试图使用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说&#34;属性,索引器或动态成员访问可能不会作为out或ref参数传递。&#34;在这些方面:

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

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

3 个答案:

答案 0 :(得分:2)

这是因为您的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);            
    }

答案 1 :(得分:1)

作为ref传递的参数可以由被调用的方法读取和写入。属性就像一个带有getter和setter的对象(好吧,它不需要同时具有这两个),并且不能假设getter和setter具有相同的后备字段。因此,不可能/允许将属性作为ref参数传递。

答案 2 :(得分:1)

问题是使用ref参数,你必须提供在C ++中被认为是指针的东西。一个财产不会做,因为这只不过是一种带有一些语法糖的方法(或两种方法)。属性将为您提供值,而不是内存地址。

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

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

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