2016-11-13 9 views
0

OpenGL을 처음 사용하고 OpenGL 함수에 간단한 C# 바인딩 인 SharpGL을 사용하여 연구했습니다. 가장 간단한 버텍스 및 프래그먼트 쉐이더를 사용하려고합니다. 프래그먼트 셰이더가 자체적으로 출력을 생성 할 때 모든 것이 문제가되지 않지만 버텍스 쉐이더에서 가져온 데이터를 사용하려고하면 검은 색 화면 만 남습니다. 셰이더는 성공적으로 컴파일되어 프로그램에 연결됩니다. OpenGL은 오류를 반환하지 않았습니다. 수많은 기사, 예제 및 자습서를 읽은 후에도 왜 그런 일이 발생하는지 아직 알 수 없습니다. 여기 버텍스 쉐이더입니다.버텍스 쉐이더에서 프래그먼트 쉐이더로 색상을 전달할 수 없습니다.

#version 330 

layout(location = 0) in vec3 position; 
layout(location = 1) in vec3 color; 

out vec3 rgb; 

void main() 
{ 
    rgb = vec3(1.0, 0.5, 0.5); 
    gl_Position = vec4(position, 1.0); 
} 

조각 쉐이더 : 여기

#version 330 

in vec3 rgb; 

out vec3 outColor; 

void main() 
{ 
    //outColor = rgb; // black display 
    outColor = vec3(1.0, 0.0, 0.4); // works fine 
} 

는 초기화 코드이다 :

gl.GenVertexArrays(1, arrayBuffer); 
gl.BindVertexArray(arrayBuffer[0]); 

gl.GenBuffers(1, pointsBuffer); 
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, pointsBuffer[0]); 
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, triangle, OpenGL.GL_STATIC_DRAW); 

gl.GenBuffers(1, colorsBuffer); 
gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, colorsBuffer[0]); 
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, colors, OpenGL.GL_STATIC_DRAW); 

그리고 마지막으로 여기에 모든 반복에 무슨 일이 생긴 무슨이다 :

gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT); 

gl.UseProgram(program.Id); 

gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, pointsBuffer[0]); 
gl.EnableVertexAttribArray(0); 
gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero); 

gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, colorsBuffer[0]); 
gl.EnableVertexAttribArray(1); 
gl.VertexAttribPointer(1, 3, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero); 

gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 12); 

gl.DisableVertexAttribArray(0); 
gl.DisableVertexAttribArray(1); 

UP D 1. 다음은 버퍼로 전달되는 데이터입니다.

private float[] triangle = { 
    -0.5f, -0.5f, 0.0f, 
    0.5f, -0.5f, 0.0f, 
    0.0f, 0.5f, 0.0f, 
}; 

private float[] colors = { 
    1.0f, 0.0f, 0.0f, 
    0.5f, 1.0f, 0.0f, 
    0.0f, 0.5f, 0.0f 
}; 
private uint[] arrayBuffer = new uint[1]; 
private uint[] pointsBuffer = new uint[1]; 
private uint[] colorsBuffer = new uint[1]; 

UPD 2 여기 쉐이더 컴파일 코드를입니다

private uint CompileProgram(OpenGL gl, List<ShaderMetadata> shaders) 
{ 
    var program = gl.CreateProgram(); 

    shaders.ForEach(shader => gl.AttachShader(program, CompileShader(gl, shader.Path, shader.Mode))); 

    gl.LinkProgram(program); 

    var status = ProgramErrorInfo(gl, program); 
    if (!String.IsNullOrEmpty(status)) 
    { 
     throw new ArgumentException(status); 
    } 

    return program; 
} 

private uint CompileShader(OpenGL gl, string path, uint kind) 
{ 
    using (var fs = new FileStream(path, FileMode.Open)) 
    { 
     using (var reader = new StreamReader(fs)) 
     { 
      var program = reader.ReadToEnd(); 
      var id = gl.CreateShader(kind); 
      gl.ShaderSource(id, program); 
      gl.CompileShader(id); 

      var status = ShaderErrorInfo(gl, id); 
      if (!String.IsNullOrEmpty(status)) 
      { 
       throw new ArgumentException(status); 
      } 

      return id; 
     } 
    } 
} 

private string ShaderErrorInfo(OpenGL gl, uint shaderId) 
{ 
    StringBuilder builder = new StringBuilder(2048); 
    gl.GetShaderInfoLog(shaderId, 2048, IntPtr.Zero, builder); 
    return builder.ToString(); 
} 

private string ProgramErrorInfo(OpenGL gl, uint programId) 
{ 
    StringBuilder builder = new StringBuilder(2048); 
    gl.GetProgramInfoLog(programId, 2048, IntPtr.Zero, builder); 
    return builder.ToString(); 
} 

3 그리고 여기 컴파일러는 flat 모두 밖으로와 rgb을의에서 추가

var programId = CompileProgram(gl, new List<ShaderMetadata> 
      { 
       new ShaderMetadata(
        @"vertex.shader", 
        OpenGL.GL_VERTEX_SHADER), 
       new ShaderMetadata(
        @"fragment.shader", 
        OpenGL.GL_FRAGMENT_SHADER) 
      }); 
+1

쉐이더 프로그램을 만드는 코드가 보이지 않습니다. – JojOatXGME

+0

@JojOatXGME UPD 2 및 3에 첨부 됨 –

+0

C#에 대한 나의 무관심을 용서하십시오. 그러나 모든 정점 데이터를 저장하는 단일 부호없는 정수를 보유 할만큼 배열이 충분히 커야 만합니까? 각'float' 컴포넌트는 단일 정수와 같은 크기입니다. –

답변

0

글쎄, 그것은 추첨 후 셰이더 프로그램을 마운트 해제하여 해결되었습니다 : 사람이 설명 또는 문서 또는 무언가에 대한 참조가있는 경우

gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 12); 
gl.UseProgram(0); 

어쨌든, 당신은 환영합니다.

-1

시도를 호출하는 방법은 UPD . 이렇게하면 보간 단계가 방지되고 꼭지점 출력이 단편 입력에 직접 매핑됩니다. 삼각형 채색으로 원하는 결과를 얻을 수는 없지만 문제를 격리하는 데 도움이됩니다.

+0

그는 * 상수 값을 전달 중입니다. *; 어떻게 보간 될 수 있습니까? –

+0

@ NicolBolas 네 말이 맞아, 아마 이걸 기초로하지 않을거야. 버텍스에서 조각 쉐이더로 정수를 전달하려고 할 때 비슷한 문제가 있었는데, '평면'이 필요합니다. – rubics5