Java JOGL OpenGL仅在奇怪条件下渲染

Java JOGL OpenGL仅在奇怪条件下渲染,java,opengl,jogl,Java,Opengl,Jogl,我目前正在尝试一个非常简单的程序。它只是在黑色背景上显示一个白色十字。问题是,我的十字架只是在奇怪的条件下才能呈现。到目前为止,我已经了解了所有这些情况: 顶点着色器位置输入的布局必须大于2 对glBindVertexArray(0)的任何调用都会导致即使在调用glBindVertexArray(数组) 每次抽签前,我都必须调用glUseProgram 正如你可能看到的,我已经不知道这里到底发生了什么。如何修复此错误 代码如下: int axesVBO; int axesVAO; int ver

我目前正在尝试一个非常简单的程序。它只是在黑色背景上显示一个白色十字。问题是,我的十字架只是在奇怪的条件下才能呈现。到目前为止,我已经了解了所有这些情况:

  • 顶点着色器位置输入的布局必须大于2
  • glBindVertexArray(0)
    的任何调用都会导致即使在调用
    glBindVertexArray(数组)
  • 每次抽签前,我都必须调用
    glUseProgram
  • 正如你可能看到的,我已经不知道这里到底发生了什么。如何修复此错误

    代码如下:

    int axesVBO;
    int axesVAO;
    int vert, frag;
    int program;
    
    @Override
    public void display(GLAutoDrawable drawable) {
        System.out.println("Render");
        GL4 gl = drawable.getGL().getGL4();
    
        gl.glClear(GL4.GL_COLOR_BUFFER_BIT | GL4.GL_DEPTH_BUFFER_BIT);
    
        gl.glBindVertexArray(axesVAO);
    
        gl.glUseProgram(program); //Doesnt work without
    
        gl.glDrawArrays(GL4.GL_LINES, 0, 2);
        gl.glDrawArrays(GL4.GL_LINES, 2, 2);
        gl.glBindVertexArray(0); //After this line the cross isn't renderd anymore
    }
    
    @Override
    public void dispose(GLAutoDrawable drawable) {
        GL4 gl = drawable.getGL().getGL4();
    
        gl.glDeleteBuffers(1, IntBuffer.wrap(new int[]{axesVBO}));
        gl.glDeleteVertexArrays(1, IntBuffer.wrap(new int[]{axesVAO}));
        gl.glDeleteProgram(program);
        gl.glDeleteShader(vert);
        gl.glDeleteShader(frag);
    }
    
    @Override
    public void init(GLAutoDrawable drawable) {
        System.out.println("Init");
        GL4 gl = drawable.getGL().getGL4();
    
        IntBuffer buffer = Buffers.newDirectIntBuffer(2);
        gl.glGenBuffers(1, buffer);
        axesVBO = buffer.get(0);
    
        vert = gl.glCreateShader(GL4.GL_VERTEX_SHADER);
        frag = gl.glCreateShader(GL4.GL_FRAGMENT_SHADER);
    
        gl.glShaderSource(vert, 1, new String[]{"#version 410\n in vec2 pos;void main() {gl_Position = vec4(pos, 0, 1);}"}, null);
        gl.glShaderSource(frag, 1, new String[]{"#version 410\n out vec4 FragColor;void main() {FragColor = vec4(1, 1, 1, 1);}"}, null);
    
        gl.glCompileShader(vert);
        gl.glCompileShader(frag);
    
        if(GLUtils.getShaderiv(gl, vert, GL4.GL_COMPILE_STATUS) == GL.GL_FALSE) {
            System.out.println("Vertex shader compilation failed:");
            System.out.println(GLUtils.getShaderInfoLog(gl, vert));
        } else {
            System.out.println("Vertex shader compilation sucessfull");
        }
    
        if(GLUtils.getShaderiv(gl, frag, GL4.GL_COMPILE_STATUS) == GL.GL_FALSE) {
            System.out.println("Fragment shader compilation failed:");
            System.out.println(GLUtils.getShaderInfoLog(gl, frag));
        } else {
            System.out.println("Fragment shader compilation sucessfull");
        }
    
        program = gl.glCreateProgram();
    
        gl.glAttachShader(program, vert);
        gl.glAttachShader(program, frag);
    
        gl.glBindAttribLocation(program, 2, "pos"); //Only works when location is > 2
        gl.glLinkProgram(program);
    
        if(GLUtils.getProgramiv(gl, program, GL4.GL_LINK_STATUS) == GL.GL_FALSE) {
            System.out.println("Program linking failed:");
            System.out.println(GLUtils.getProgramInfoLog(gl, program));
        } else {
            System.out.println("Program linking sucessfull");
        }
    
        gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, axesVBO);
        gl.glBufferData(GL4.GL_ARRAY_BUFFER, Float.BYTES * 8, FloatBuffer.wrap(new float[]{-1f, 0, 1f, 0, 0, 1f, 0, -1f}), GL4.GL_STATIC_DRAW);
    
        gl.glUseProgram(program);
    
        buffer.clear();
        gl.glGenVertexArrays(1, buffer);
        axesVAO = buffer.get();
        gl.glBindVertexArray(axesVAO);
    
        int pos = gl.glGetAttribLocation(program, "pos");
        gl.glEnableVertexAttribArray(pos);
    
        gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, axesVBO);
        gl.glVertexAttribPointer(pos, 2, GL4.GL_FLOAT, false, 0, 0);
        //Commented out for testing reasons (doesnt work when active)
        //gl.glBindVertexArray(0);
    
        gl.glClearColor(0f, 0f, 0f, 1f);
    }
    

    你发现的情况看起来很奇怪。总之,总的来说,拥有一个干净简单的代码有助于避免讨厌的bug。从干净简单开始,然后构建:)

    几点考虑:

    • 不要对vbo和vao使用
      int
      ,直接使用直接缓冲区
    • 不需要全局声明
      vert
      frag
      如果它们只在
      init
      中使用,则在方法中本地声明它们
    • 更喜欢使用jogl实用程序生成直接缓冲区
      GLBuffers.newDirect*Buffer(…)
    • 至少在一开始,您更愿意使用jogl实用程序(
      ShaderCode.create
      ShaderProgram
      )来编译着色器,它可以让您从工作和潜在的bug中解脱出来,并在整个着色器创建过程中对任何步骤进行更深入的检查(有时甚至太多,但现在着色器的编译速度如此之快并不重要)
    • 如果有,您可以检查
      gl4.isExtensionAvailable(“GL\u ARB\u explicit\u attrib\u location”)
      ,在任何地方都可以使用它,它将避免任何类型的位置(例如
      glbindAttriblation
      glgetAttriblation
      )的许多潜在错误和开销
    • 最好将一个直接缓冲区传递给
      glBufferData
      ,这样jogl就不必在下面自己创建它,您可以跟踪它来释放它
    • 保持
      init
      的干净和可读性。您正在将许多内容混合在一起。例如,您在开始时生成vbo,然后创建程序,然后将数据上载到vbo
    • init
      中的
      gl.glUseProgram(program);
      没有任何意义,除非您的想法是将其绑定并保持绑定状态。无论如何,通常,程序是渲染调用之前初始化阶段的一部分,因此最好在
      display()
      中移动它
    • 更喜欢
      glClearBuffer
      而不是
      glClear
    • gl.gldrawArray(GL4.gl_行,0,2);
      没有任何实用程序,因为您将零作为顶点数传递
    • 如果你需要灵感,看看这个

    嘿,新用户!我看到您在渲染图像时遇到了困难,但没有具体问题需要读者回答。您是否在寻找漏洞方面寻求帮助?特定的函数调用是否会导致问题?由于Stack Overflow是一个问答网站,如果您问特定的问题,您会得到更多的答案。祝您好运!我同意Dylan的看法。此外,JOGL也不是罪魁祸首,你只是在使用VAO和VBO时遇到了一些困难。我建议你在官方的JogAmp上问JOGL一些具体的问题forum@gouessej我不想因为错误而责怪JOGL,我只是将它添加到标题中,以明确我使用的是什么后端。显然我没有很好地解释我的情况。谢谢你的支持反正反应很快