OpenGL/JOGL抛出GL\u无效\u操作

OpenGL/JOGL抛出GL\u无效\u操作,opengl,lwjgl,jogl,Opengl,Lwjgl,Jogl,我正在为我正在开发的游戏编写关卡编辑器。我使用JOGL,似乎有问题。我习惯于LWJGL openGL调用,调整到核心openGL有点令人困惑,因为LWJGL似乎简化了很多东西 所以我的问题是,我创建了一个保存vao ID/名称和顶点计数的模型,以及一个创建模型和渲染器的模型加载程序。渲染器目前不是批处理的。我以后再做。问题是opengl抛出了一个GL\u INVALID\u操作错误。不确定是什么原因造成的。其他一切,包括我为测试环境而绘制的基本三角形,都正常工作,所以我的加载程序或渲染器中似乎存

我正在为我正在开发的游戏编写关卡编辑器。我使用JOGL,似乎有问题。我习惯于LWJGL openGL调用,调整到核心openGL有点令人困惑,因为LWJGL似乎简化了很多东西

所以我的问题是,我创建了一个保存vao ID/名称和顶点计数的模型,以及一个创建模型和渲染器的模型加载程序。渲染器目前不是批处理的。我以后再做。问题是opengl抛出了一个GL\u INVALID\u操作错误。不确定是什么原因造成的。其他一切,包括我为测试环境而绘制的基本三角形,都正常工作,所以我的加载程序或渲染器中似乎存在问题

代码如下: 型号:

}

加载器:

public class ModelLoader {
private  GL2 gl;
private List<int[]> vaos = new ArrayList<int[]>();
private List<int[]> vbos = new ArrayList<int[]>();

public ModelLoader(GL2 gl){
    this.gl = gl;
}

public JoglModel loadToVao(float[] positions){
    int vaoID = createVAO();
    storeDataInAttributeList(0,positions);
    unbind();


    return new JoglModel(vaoID,positions.length/3);
}

private int createVAO(){
    int[] vaoID = new int[1];
    gl.glGenVertexArrays(vaoID.length, vaoID, 0);
    vaos.add(vaoID);
    gl.glBindVertexArray(vaoID[0]);
    return vaoID[0];
}

private void storeDataInAttributeList(int attributeNumber,float[] data){
    int[] vboID = new int[1];
    gl.glGenBuffers(vboID.length,vboID,0);
    vbos.add(vboID);
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER,vboID[0]);
    FloatBuffer floatBuffer = createFloatBuffer(data);
    gl.glBufferData(gl.GL_ARRAY_BUFFER,floatBuffer.remaining(),floatBuffer,gl.GL_STATIC_DRAW);
    gl.glVertexAttribPointer(attributeNumber,3,gl.GL_FLOAT,false,0,0);
    gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0);

}

private FloatBuffer createFloatBuffer(float[] data){
    FloatBuffer floatBuffer = FloatBuffer.allocate(data.length);
    floatBuffer.put(data);
    floatBuffer.flip();
    return floatBuffer;
}

private void unbind(){}
public void clear(){
    for(int[] vao : vaos){
        gl.glDeleteVertexArrays(vao.length,vao,0);
    }

    for(int[] vbo: vbos){
        gl.glDeleteBuffers(vbo.length,vbo,0);
    }
    vaos.clear();
    vbos.clear();
}
私人GL2 gl

public JoglRenderer(GL2 gl){
    this.gl = gl;
}

public void begin(){
   gl.glClearColor(1f,0f,0f,1f);
   gl.glClear(gl.GL_CLEAR_BUFFER);


}

public void render(JoglModel joglModel){

    gl.glBindVertexArray(joglModel.getVaoID());
    gl.glEnableVertexAttribArray(0);
    gl.glDrawArrays(gl.GL_TRIANGLES,0,joglModel.getVertexCount());
    gl.glDisableVertexAttribArray(0);
    gl.glBindVertexArray(0);

    /*
       gl.glBegin(gl.GL_TRIANGLES);
      gl.glColor3f(1, 0, 0);
       gl.glVertex2f(-1, -1);
      gl.glColor3f(0, 1, 0);
      gl.glVertex2f(0, 1);
      gl.glColor3f(0, 0, 1);
      gl.glVertex2f(1, -1);
     gl.glEnd();
    */
}

public void checkError() {
    String errorString = "";
    int error = gl.glGetError();
    if (error != GL.GL_NO_ERROR) {

        switch (error) {
            case GL.GL_INVALID_ENUM:
                errorString = "GL_INVALID_ENUM";
                break;
            case GL.GL_INVALID_VALUE:
                errorString = "GL_INVALID_VALUE";
                break;
            case GL.GL_INVALID_OPERATION:
                errorString = "GL_INVALID_OPERATION";
                break;
            case GL.GL_INVALID_FRAMEBUFFER_OPERATION:
                errorString = "GL_INVALID_FRAMEBUFFER_OPERATION";
                break;
            case GL.GL_OUT_OF_MEMORY:
                errorString = "GL_OUT_OF_MEMORY";
                break;
            default:
                errorString = "UNKNOWN";
                break;
        }

    }
    System.out.println(errorString);
}
}

注释掉的三角形部分工作正常。在清除屏幕的方法中似乎也有一个错误,但这不是我现在关心的问题。有人能指出问题出在哪里吗

谢谢

(编辑)
所以我发现了opengl的错误。我意外地将vaoID作为顶点计数传递,反之亦然。所以我修正了错误消失的问题。但什么都没有呈现。有什么想法吗?

我在这里写了一些注意事项,因为评论太短了:

  • loadToVao
    可能会导致错误,您不会将任何内容加载到vao,vao有助于记住启用了哪些顶点属性数组、它们的布局/格式以及它们引用的vbo,这样您就不必在每一帧调用它们。它还可以存储绑定元素数组。因此,
    GlenableVertexAttributeArray
    GlDisableVertexAttributeArray
    不应进入
    render()函数中

  • 渲染器应该始终作为默认值存在,因此我建议使用一个main并在那里初始化渲染器(GLEventListener

  • 我不会在
    createVAO

  • 不要存储
    GL
    元素。使其保持瞬态(每次作为参数传递)或从
    GLContext
    获取。第一个选项可能会增加复杂性(因为每个gl调用都需要实现
    GLEventListener
    的类中的
    gl
    对象),但会简化调试(因为您确实知道gl调用的执行顺序)

  • 如果只需要一个vao,请避免为此创建
    列表
    ,vbo也是如此

  • 我建议您使用
    static final int
    变量来保存顶点属性索引。它提高了可读性并避免了潜在的bug

  • 除非不需要直接缓冲区,否则使用
    GLBuffers
    分配(直接)缓冲区

  • 那是什么?我从没见过。使用
    Float.BYTES
    GLBuffers.SIZEOF_Float

  • 正如@BDL已经说过的,查看
    glClear
    并调用
    checkError
    类似的方法,每次传递不同的字符串,以便在出现错误时轻松找出哪个调用有问题

  • Jogl确实有一个
    GL\u COLOR\u BUFFER\u位
    ,只需编写它并调用自动完成,您的IDE应该建议您正确的位置,或者如果设置正确,则自动插入正确的
    导入

  • 它看起来也缺少(可能您没有报告)的是
    glvertexattributepointer

  • 如果仍然不起作用,回到基本测试三角形,确保它起作用,然后从那里开始构建。将其在自己的类中移动到渲染器外部,使用更多几何体丰富它,使用索引绘图,ecc。每一步控制它工作,如果它不工作,那么错误在于你最后的修改


  • GL\u CLEAR\u BUFFER
    不允许作为
    glClear
    的参数。看一看这张照片。您应该找出导致无效操作的opengl函数。只需在每次opengl调用之后放置checkError函数,您就会看到问题的根源。谢谢。那是个好主意。关于颜色缓冲区。JOGL似乎没有GL\u颜色\u缓冲\u位。不知道为什么。(编辑)别担心。我这样做是不对的。忘了它是一个静态整数。GL.GL\u颜色\u缓冲\u位是一种方法。现在我正在诊断是哪个gl函数导致了错误。我们是否错过了着色器程序?你看到清晰的颜色了吗?是的,清晰的颜色显示出来了,现在效果非常好。但不是它应该渲染的四边形。
    public class JoglRenderer {
    
    public JoglRenderer(GL2 gl){
        this.gl = gl;
    }
    
    public void begin(){
       gl.glClearColor(1f,0f,0f,1f);
       gl.glClear(gl.GL_CLEAR_BUFFER);
    
    
    }
    
    public void render(JoglModel joglModel){
    
        gl.glBindVertexArray(joglModel.getVaoID());
        gl.glEnableVertexAttribArray(0);
        gl.glDrawArrays(gl.GL_TRIANGLES,0,joglModel.getVertexCount());
        gl.glDisableVertexAttribArray(0);
        gl.glBindVertexArray(0);
    
        /*
           gl.glBegin(gl.GL_TRIANGLES);
          gl.glColor3f(1, 0, 0);
           gl.glVertex2f(-1, -1);
          gl.glColor3f(0, 1, 0);
          gl.glVertex2f(0, 1);
          gl.glColor3f(0, 0, 1);
          gl.glVertex2f(1, -1);
         gl.glEnd();
        */
    }
    
    public void checkError() {
        String errorString = "";
        int error = gl.glGetError();
        if (error != GL.GL_NO_ERROR) {
    
            switch (error) {
                case GL.GL_INVALID_ENUM:
                    errorString = "GL_INVALID_ENUM";
                    break;
                case GL.GL_INVALID_VALUE:
                    errorString = "GL_INVALID_VALUE";
                    break;
                case GL.GL_INVALID_OPERATION:
                    errorString = "GL_INVALID_OPERATION";
                    break;
                case GL.GL_INVALID_FRAMEBUFFER_OPERATION:
                    errorString = "GL_INVALID_FRAMEBUFFER_OPERATION";
                    break;
                case GL.GL_OUT_OF_MEMORY:
                    errorString = "GL_OUT_OF_MEMORY";
                    break;
                default:
                    errorString = "UNKNOWN";
                    break;
            }
    
        }
        System.out.println(errorString);
    }