2014-01-14 36 views
2

我正在使用OpenGL和LWJGL以及我自己非常小的框架來處理簡單的任務。我正在關注該書OpenGL SuperBible:綜合教程和參考(第6版)GL_INVALID_OPERATION在Tesselation着色器上

我會列出我的計劃中最重要的部分:

public class GameController extends Controller { 
    private Program test1Program; 
    private int vaoId; 

    @Override 
    protected void init() { 
     glViewport(0, 0, 800, 600); 
     test1Program = new Program(
       new VertexShader("src/shaders/test.vert.glsl").create(), 
       new ControlShader("src/shaders/test.cont.glsl").create(), 
       new EvaluationShader("src/shaders/test.eval.glsl").create(), 
       new FragmentShader("src/shaders/test.frag.glsl").create() 
       ).create(); 
     vaoId = glGenVertexArrays(); 
     glBindVertexArray(vaoId); 
    } 

    @Override 
    protected void draw(double msDelta) { 
     glClearColor((float)Math.sin(currentTime/1000f) * 0.5f + 0.5f, (float)Math.cos(currentTime/1000f) * 0.5f + 0.5f, 0.0f, 1.0f); 
     glClear(GL_COLOR_BUFFER_BIT);   
     test1Program.use(); 
     glVertexAttrib4f(0, (float)Math.sin(currentTime/1000f) * 0.5f, (float)Math.cos(currentTime/1000f) * 0.5f, 0.0f, 0.0f); 
     glVertexAttrib4f(1, (float)Math.sin(currentTime/1000f * 2f) * 0.5f + 0.5f, (float)Math.cos(currentTime/1000f * 2f) * 0.5f + 0.5f, 0.0f, 1.0f); 
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
     glDrawArrays(GL_TRIANGLES, 0, 3); 
    } 

    @Override 
    protected void shutdown() { 
     test1Program.delete(); 
     glDeleteVertexArrays(vaoId); 
    } 

    public static void main(String[] args) { 
     Controller controller = new GameController(); 
     controller.start(); 
    } 
} 

我定製VertexShaderControlShaderEvaluationShaderFragmentShader的工作,如果着色器代碼不能正常編譯或沒有得到正確的連接,一個異常將被拋出,我會注意到它。所以我已經驗證那些和Program工作正常。

錯誤(Exception in thread "main" org.lwjgl.opengl.OpenGLException: Invalid operation (1282))被拋到glDrawArrays調用。

test.vert.glsl:

#version 440 core 

layout(location = 0) in vec4 offset; 
layout(location = 1) in vec4 color; 

out VS_OUT { 
    vec4 color; 
} vs_out; 

void main() { 
    const vec4 vertices[3] = vec4[3](
     vec4(0.25, -0.25, 0.5, 1.0), 
     vec4(-0.25, -0.25, 0.5, 1.0), 
     vec4(0.25, 0.25, 0.5, 1.0) 
    ); 
    gl_Position = vertices[gl_VertexID] + offset; 
    vs_out.color = color; 
} 

test.cont.glsl:

#version 440 core 

layout(vertices = 3) out; 

void main() { 
    if (gl_InvocationID == 0) { 
     gl_TessLevelInner[0] = 5.0; 
     gl_TessLevelOuter[0] = 5.0; 
     gl_TessLevelOuter[1] = 5.0; 
     gl_TessLevelOuter[2] = 5.0; 
    } 
    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 
} 

test.eval.glsl:

#version 440 core 

layout(triangles, equal_spacing, cw) in; 

void main() { 
    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position); 
} 

#version 440 core 

in VS_OUT { 
    vec4 color; 
} fs_in; 

out vec4 color; 

void main() { 
    color = fs_in.color; 
} 

我已經三重檢查了我所有的代碼,並且對這本書進行了交叉檢查,但不知道爲什麼它不工作。如果需要,我將不勝感激,並希望能提供更多信息。

+0

對於那個downvoter:給downvote一個**理由**。我不遵守發佈標準的哪一部分? – skiwi

+0

代碼是否與默認管道一起工作(即沒有test1Program)?也只是爲了安全,在渲染之前再次綁定VAO。 – Njol

+0

@Njol這段代碼只處理了一個'VertexShader'和一個'FragmentShader'。只是驗證它與默認管道一起運行。 – skiwi

回答

5

我找到了答案剛纔:

glDrawArrays(GL_TRIANGLES, 0, 3); 

需要是:

glDrawArrays(GL_PATCHES, 0, 3); 

從OpenGL的一些更多的努力來證明什麼是錯就好了。

也沒有在書中明確提到我需要使用GL_PATCHES,我只是通過查看書中可編譯示例的源代碼來了解它。

+0

出現同樣的問題。感謝分享。不過,我還有其他問題。我必須忽略攜帶顏色數據的接口塊,並在片段着色器中對其進行硬編碼以顯示任何內容。我希望我能理解爲什麼更進一步。 – broncoAbierto

0

在對着色器進行了更徹底的調查之後,我懷疑部分問題是在所有階段鏈接後,程序中沒有頂點屬性1(layout(location = 1) in vec4 color)。這可能不是你的全部問題,但現在你的GLSL計劃不會按照你想要的方式行事。

您必須將通過鑲嵌着色器階段輸入到頂點着色器中的數據傳遞到片段着色器階段 - 如果不這樣做,那麼GLSL編譯器/鏈接器將確定該頂點屬性未被使用當程序執行時並沒有給它分配一個位置。這種行爲也適用於制服。

看看我寫在SO上的另一個答案explanation on how to do this