2011-01-16 8 views
2

おはようございます、VBO OS XとWin7の違いは?

問題は、OpenGLタイルグリッドを表示するWin7(C#、VS2010)で書かれたコードが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がどのように頂点属性を扱うのかという面白い違いがありますか?

ありがとうございます。問題を見つけるのに役立つコードが必要な場合はお知らせください。

注:私は(均一に)シェーダーのオフセット頂点を格納し、タイルごとにそれにそれを更新することができます。これは動作します!だから、最初のVBOだけがバインドされており、100回レンダリングされていると私は考えています。

答えて

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); 
} 
+0

OpenGLの実装を担当するIHVドライバはWindows 7ではありません。 –

+0

十分に公正です。コンピュータは、異なるベンダーのグラフィックスカードを使用しています。ありがとう – Giawa