2015-02-07 12 views
0

일부 구식 OpenGL 코드를 최신 OpenGL4로 업데이트하려고합니다.OpenGL4에서 VBOs/VAO를 사용하여 렌더링

거대한 질감의 큐브 모델을 미리 렌더링 할 수 있습니다. 대신 그

, 나는 지금이납니다 :

흰색 배경에 반 임의의 검은 삼각형의 필드의 Failure

.

내 VAO/VBO 코드 구축 :

 // Normal buffer 
     GL.GenBuffers(1, out VBONormals); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals); 
     GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Normals.Length * Vector3.SizeInBytes), 
     Normals, BufferUsageHint.StaticDraw); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 
     // TexCoord buffer 
     GL.GenBuffers(1, out VBOTexCoords); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords); 
     GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(TexCoords.Length * Vector3.SizeInBytes), 
     TexCoords, BufferUsageHint.StaticDraw); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 
     // Vertex buffer 
     GL.GenBuffers(1, out VBO); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); 
     GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Positions.Length * Vector3.SizeInBytes), 
     Positions, BufferUsageHint.StaticDraw); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 
     // Index buffer 
     GL.GenBuffers(1, out VBOIndices); 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices); 
     GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(Indices.Length * sizeof(uint)), 
     Indices, BufferUsageHint.StaticDraw); 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); 
     GL.GenVertexArrays(1, out VAO); 
     GL.BindVertexArray(VAO); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); 
     GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 0, 0); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals); 
     GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 0, 0); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords); 
     GL.VertexAttribPointer(2, 3, VertexAttribPointerType.Float, false, 0, 0); 
     GL.EnableVertexAttribArray(0); 
     GL.EnableVertexAttribArray(1); 
     GL.EnableVertexAttribArray(2); 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices); 
     // Clean up 
     GL.BindVertexArray(0); 
     GL.DisableVertexAttribArray(0); 
     GL.DisableVertexAttribArray(1); 
     GL.DisableVertexAttribArray(2); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, 0); 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); 

를하고 코드 렌더링 :

 VBOTexture.Bind(); 
     GL.BindVertexArray(VAO); 
     //GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); 
     GL.DrawArrays(PrimitiveType.Triangles, 0, Indices.Length); 

버텍스 쉐이더 :

#version 430 core 

layout (location = 0) in vec3 position; 
layout (location = 1) in vec3 normal; 
layout (location = 2) in vec3 texcoord; 

layout (location = 1) uniform mat4 projection; 

layout (location = 0) out vec3 f_color; 

void main() 
{ 
    f_color = normal; 
    gl_Position = projection * vec4(position, 1.0); 
} 

조각 쉐이더 :

#version 430 core 

layout (binding = 0) uniform sampler2D tex; 

layout (location = 0) in vec3 f_color; 

out vec4 color; 

void main() 
{ 
    vec4 tcolor = texture2D(tex, gl_TexCoord[0].st); 
    float dist = 0.0; 
    if (gl_TexCoord[0].x < 0.5) 
    { 
     dist = gl_TexCoord[0].x; 
    } 
    else 
    { 
     dist = 1.0 - gl_TexCoord[0].x; 
    } 
    if (gl_TexCoord[0].y < 0.5) 
    { 
     dist *= gl_TexCoord[0].y; 
    } 
    else 
    { 
     dist *= 1.0 - gl_TexCoord[0].y; 
    } 
    dist *= 32; 
    dist = min(1, dist); 
    color = vec4(tcolor[0] * dist, tcolor[1] * dist, tcolor[2] * dist, tcolor[3]); 
} 
,691,363을210

그리기 호출을 주석 처리 된 호출로 전환하면 동일한 결과가 생성됩니다.

또한주의 : 원래 코드가 정확히 동일 뺀 VAO 청크,이 렌더링 :

(I는 관련이없는 이유 Vector3에 Vector2에서 texcoords 전환 제외)
 GL.PushClientAttrib(ClientAttribMask.ClientVertexArrayBit); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBONormals); 
     GL.NormalPointer(NormalPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero); 
     GL.EnableClientState(ArrayCap.NormalArray); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBOTexCoords); 
     GL.TexCoordPointer(2, TexCoordPointerType.Float, Vector2.SizeInBytes, IntPtr.Zero); 
     GL.EnableClientState(ArrayCap.TextureCoordArray); 
     GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); 
     GL.VertexPointer(3, VertexPointerType.Float, Vector3.SizeInBytes, IntPtr.Zero); 
     GL.EnableClientState(ArrayCap.VertexArray); 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, VBOIndices); 
     GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); 
     GL.PopClientAttrib(); 

어디서 잘못 됐습니까?

+0

하지만 일반적으로 인해 성능 쉐이더에서'conditionals'을 피하려고은 – MickyD

+0

그 코드가 있었다 명중 임시 개념 증명, 그것은 사소한 최적화 아니에요. – mcmonkey4eva

+0

음,'glDrawArrays()'호출은 개념적으로 완전히 잘못되었습니다. 특히'Indices.Leght'가 중요합니다. 'glDrawRangeElements()'는 원칙적으로 작동해야합니다. 두 호출이 모두 같은 결과를 내면 인덱스 배열은 첫 번째 n 개의 정수 (0 포함)의 사소한 경우이거나 데이터가 어딘가에있는 경우가 있습니다. 그냥 – derhass

답변

1

이전 코드는 drawElements이지만 새 코드는 drawArrays입니다.

VBOTexture.Bind(); 
    GL.BindVertexArray(VAO); 
    //GL.DrawRangeElements(PrimitiveType.Triangles, 0, Positions.Length, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); 
    GL.DrawElements(PrimitiveType.Quads, Indices.Length, DrawElementsType.UnsignedInt, IntPtr.Zero); 
오프 주제
+1

'PrimitiveType.Quads'는 오타가 있습니까? 색인 버퍼가 삼각형을 저장하는 것처럼 보이고 코어 GL에 쿼드가 없습니다. –

+0

@ColonelThirtyTwo 그가 원래 코드 –

+0

에서 사용했던 것입니다 ... 제가 우연히 삼각형에서 쿼드로 또는 그 반대로 전환하지 않았다고 말해주세요. 왜냐하면 그것은 모든 것을 아주 잘 설명하기 때문입니다 ... – mcmonkey4eva