2015-06-27 76 views
-1

我在使用OpenGL 4.4编写OpenTK的2D游戏。使用颜色和纹理UV坐标和矩阵我可以成功地绘制顶点之间的纹理与顶点着色器:片段着色引发的OpenGL错误

公共常量字符串vertexShaderDefaultSrc = @” 的#Version 330

 uniform mat4 MVPMatrix; 

     layout (location = 0) in vec2 Position; 
     layout (location = 1) in vec2 Texture; 
     layout (location = 2) in vec4 Colour; 

     out vec2 InTexture; 
     out vec4 OutColour; 

     void main() 
     { 
      gl_Position = MVPMatrix * vec4(Position, 0, 1); 
      InTexture = Texture; 
      OutColour = Colour; 
     }"; 

和片段着色器:

public const string fragmentShaderDefaultSrc = 
    @" 
    #version 330 

    uniform sampler2D Sampler; 

    in vec2 InTexture; 
    in vec4 OutColour; 

    out vec4 OutFragColor; 

    void main() 
    { 
     OutFragColor = texture(Sampler, InTexture) * OutColour; 

     //Alpha test 
     if(OutFragColor.a <= 0) 
      discard; 
    } 
    "; 

但是如果我想绘制一个纯色而不是纹理,我使用这个着色器(使用相同的顶点,传递不会被使用的UV坐标):

public const string fragmentShaderSolidColourSrc = 
    @" 
    #version 330 

    uniform sampler2D Sampler; 

    in vec2 InTexture; 
    in vec4 OutColour; 

    out vec4 OutFragColor; 

    void main() 
    { 
     OutFragColor = OutColour; 

     //Alpha test 
     if(OutFragColor.a <= 0) 
      discard; 
    } 
    "; 

现在这个工作很好,但OpenGL报告错误 - GL_INVALID_VALUE。它画得很好,一切似乎都起作用,但理想情况下,我希望OpenGL在这种情况下无错,这样我就可以捕捉到真正的错误。我会很感激任何帮助,并且可以共享更详细的着色器如何编译或使用,如果这有帮助的 - 我不明白的是默认着色器如何工作,但纯色不。

我已经找到了错误的确切来源,我的渲染调用(着色器编译没有问题)

GL.EnableVertexAttribArray(shader.LocationPosition); 
     GL.VertexAttribPointer(shader.LocationPosition, 2, VertexAttribPointerType.Float, false, Stride, 0); 
     //-----everything up to here is fine 

     //this line throws an error 
     GL.EnableVertexAttribArray(shader.LocationTexture); 
     //as does this line 
     GL.VertexAttribPointer(shader.LocationTexture, 2, VertexAttribPointerType.Float, false, Stride, 8); 


     //this is all ok 
     GL.EnableVertexAttribArray(shader.LocationColour); 
     GL.VertexAttribPointer(shader.LocationColour, 4, VertexAttribPointerType.UnsignedByte, true, Stride, 16); 

     //ok 
     GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer); 
     GL.DrawArrays(DrawType, 0, Vertices.Length); 

     //ok 
     GL.DisableVertexAttribArray(shader.LocationPosition); 

     //this line throws error 
     GL.DisableVertexAttribArray(shader.LocationTexture); 

     //this is ok 
     GL.DisableVertexAttribArray(shader.LocationColour); 
+0

OpenGL何时报告错误?着色器编译?着色器链接?捆绑 ?画画 ?你能提供围绕错误的代码吗? –

+0

编辑显示确切的错误来源(在渲染中)。 –

+0

这表明shader.LocationTexture具有无效值。你应该检查你初始化的那一行。否则,如果你不需要纹理,你也不需要纹理坐标。 –

回答

0

在我看来,一些测试后(将是不错的有这样的验证),如果编译器不会使用像纹理坐标这样的变量,所以调用它来获取它的位置返回-1。只需检查locationTexture是否为-1,然后不绑定locationTexture等,如果这样可以解决我的问题。

+1

是的,情况正是如此。只有_active_属性(与制服相同)确实有位置。着色器编译器/链接器通常非常积极地优化不影响最终输出的所有内容。请注意,对于制服来说,设置位置为-1的制服明确定义为不是错误(它只是默默忽略),但对于属性而言,这是不同的。您可以查询的位置是带符号的int,可能是-1,但顶点attrib函数的索引是无符号的,并且使用[0,max_attrib-1]范围之外的索引始终是错误。 – derhass

+0

正是我在找的,谢谢你 –