2016-11-13 9 views
0

Я новичок в OpenGL и изучаю его с помощью SharpGL, который является простым связыванием C# с функциями OpenGL. Я пытаюсь использовать простейшие шейдеры вершин и фрагментов. Когда фрагментарный шейдер генерирует вывод сам по себе, все в порядке, но когда он пытается использовать данные, полученные из вершинного шейдера, есть только черный экран. Шейдеры успешно скомпилированы и связаны с программой. 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(); 
} 

UPD 3 А вот как компилятор вызывается

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

Попробуйте добавить flat в оба, и в из rgb , Это предотвращает шаг интерполяции и отображает вывод вершин непосредственно на вход фрагмента. Хотя это может не дать вам результат, который вы хотите с помощью цвета треугольника, это поможет вам изолировать проблему.

+0

Он передает * постоянное значение *; как он может быть интерполирован? –

+0

@NicolBolas, вы правы, я, вероятно, не знаю этого. Я забыл о подобной проблеме, которую я испытывал при попытке передать целые числа из вершин в фрагментарные шейдеры, для которых требуется «flat». – rubics5

Смежные вопросы