VBO和Win7之间的VBO差异?

时间:2011-01-16 23:39:48

标签: opengl glsl tao-framework

下午好,

问题是在Win7(C#,VS2010)上编写的显示OpenGL磁贴网格的代码在Mac OS X(C#,MonoDevelop)中的显示方式不同。每个图块当前单独渲染,并且x / y偏移实际存储在顶点信息中。瓷砖的构建方式如下:

private void BuildTile()
{
    Vector3[] vertices = new Vector3[4];
    Vector2[] uvs = new Vector2[] { new Vector2(0, 1), new Vector2(0, 0), new Vector2(1, 1), new Vector2(1, 0) };
    int[] indices = new int[] { 1, 0, 2, 1, 2, 3 };

    // build vertex list based on position
    vertices[0] = new Vector3(Location.X, Location.Y + 1, 0);
    vertices[1] = new Vector3(Location.X, Location.Y, 0);
    vertices[2] = new Vector3(Location.X + 1, Location.Y + 1, 0);
    vertices[3] = new Vector3(Location.X + 1, Location.Y, 0);

    VBO<Vector3> vertex = new VBO<Vector3>(vertices, BufferTarget.ArrayBuffer, BufferUsageHint.StaticRead);
    VBO<Vector2> uv = new VBO<Vector2>(uvs, BufferTarget.ArrayBuffer, BufferUsageHint.StaticRead);
    VBO<int> element = new VBO<int>(indices, BufferTarget.ElementArrayBuffer, BufferUsageHint.StaticRead);

    VAO = new VAO(ShaderProgram, vertex, uv, element);
}

由于Mac OS X不支持OpenGL 3,因此每次进行绘制调用时,VAO对象都会绑定属性。

    public void BindAttributes()
    {
        if (vertex == null) throw new Exception("Error binding attributes.  No vertices were supplied.");
        if (element == null) throw new Exception("Error binding attributes.  No element array was supplied.");
        uint array = 0;

        Gl.EnableVertexAttribArray(array);
        Gl.BindAttribLocation(Program.ProgramID, array, "in_position");
        Gl.BindBuffer(vertex.BufferTarget, vertex.vboID);
        Gl.VertexAttribPointer(array++, vertex.Size, vertex.PointerType, true, 12, new IntPtr(0));

        Gl.EnableVertexAttribArray(array);
        Gl.BindAttribLocation(Program.ProgramID, array, "in_uv");
        Gl.BindBuffer(uv.BufferTarget, uv.vboID);
        Gl.VertexAttribPointer(array++, uv.Size, uv.PointerType, true, 8, new IntPtr(0));

        Gl.BindBuffer(BufferTarget.ElementArrayBuffer, element.vboID);
    }

着色器非常简单。顶点着色器:

uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;

attribute vec3 in_position;
attribute vec2 in_uv;

varying vec2 uv;

void main(void)
{
  uv = in_uv;

  gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
}

片段着色器:

uniform sampler2D active_texture;

varying vec2 uv;

void main(void)
{
  gl_FragColor = texture2D(active_texture, uv);
}

问题是Mac OS X版本覆盖了所有磁贴。所有100个瓷砖将在第一个瓷砖的位置堆叠在彼此之上。但是,在Win7上,磁贴将按预期分布在10x10网格中。有谁知道为什么会发生这种情况?我查看了顶点数据,它在Mac OS X和Win7上存储偏移量,VBO ID是唯一的,正确的VBO被绑定。我猜我的方法绑定属性一定有问题,但我看不出问题。 OpenGL 2和3如何处理顶点属性之间有一些有趣的区别吗?

谢谢,如果您需要我的代码以帮助我找到问题,请告诉我。

注意:我可以在着色器中存储顶点偏移(作为一个统一)并按照每个tile更新它。这有效!因此,我会相信只有第一个VBO被绑定,并且只被渲染了100次。

1 个答案:

答案 0 :(得分:1)

事实证明,在链接程序后无法绑定属性位置。然而,无论出于何种原因,我的Win7 PC(带有Radeon驱动程序)决定允许它。以下是实际绑定属性的方法。

public void BindAttributes()
{
    if (vertex == null) throw new Exception("Error binding attributes.  No vertices were supplied.");
    if (element == null) throw new Exception("Error binding attributes.  No element array was supplied.");

    uint loc = (uint)Gl.GetAttribLocation(Program.ProgramID, "in_position");
    Gl.EnableVertexAttribArray(loc);
    Gl.BindBuffer(vertex.BufferTarget, vertex.vboID);
    Gl.VertexAttribPointer(loc, vertex.Size, vertex.PointerType, true, 12, new IntPtr(0));


    loc = (uint)Gl.GetAttribLocation(Program.ProgramID, "in_uv");
    Gl.EnableVertexAttribArray(loc);
    Gl.BindBuffer(uv.BufferTarget, uv.vboID);
    Gl.VertexAttribPointer(loc, uv.Size, uv.PointerType, true, 8, new IntPtr(0));

    Gl.BindBuffer(BufferTarget.ElementArrayBuffer, element.vboID);
}