Java opengl 3.2抽屉组件,只有一个四视图

Java opengl 3.2抽屉组件,只有一个四视图,java,opengl,game-engine,Java,Opengl,Game Engine,编辑:我应该澄清一下 我就是这样计划事情的: 每次应用程序渲染(60hz)时,我都希望将要渲染的所有顶点放入一个巨大的缓冲区。然后,该缓冲区将上载到GPU。(glBufferdata) 然后,我将使用gldrawerelements在一个调用中呈现整个内容 这就是我试图实现它的方式: 设置: 1.创建一个巨大的浮动缓冲区(java) 2.在我的VOB中(这对我来说仍然有点虚幻,但我认为我做对了。)我使用EBO来减少顶点 呈现: 1.在我的浮动缓冲区中放置大量顶点 2.将我的浮动缓冲区上载到GPU

编辑:我应该澄清一下

我就是这样计划事情的:

  • 每次应用程序渲染(60hz)时,我都希望将要渲染的所有顶点放入一个巨大的缓冲区。然后,该缓冲区将上载到GPU。(glBufferdata)

  • 然后,我将使用gldrawerelements在一个调用中呈现整个内容

  • 这就是我试图实现它的方式:

    设置: 1.创建一个巨大的浮动缓冲区(java) 2.在我的VOB中(这对我来说仍然有点虚幻,但我认为我做对了。)我使用EBO来减少顶点

    呈现: 1.在我的浮动缓冲区中放置大量顶点 2.将我的浮动缓冲区上载到GPU 3.用元素渲染它

    结果: 第一个四边形渲染良好。其余的都不渲染

    问题 为什么不是所有的四边形都渲染

    下面是我如何使用Renderer2类的:

    r=新渲染器(); 循环: bind(); 对于很多很多物体。。。 Renderer.render(x1,x2,y1,y2,颜色顶部,颜色底部); ... Renderer.flush(); 断环

    public class Renderer2
    {
        private util.ShaderProgram shaderProgram;
    
    private int vaoID;
    private int vboVertID;
    private int eboID;
    
    FloatBuffer vboBuff;
    
    private final int floatsPerQuad = 6;
    private int nrOfVert = 0;
    
    
    public Renderer2(){
        String VERTEX = "#version 330 core" + "\n"
                + "layout(location = 0) in vec2 position;" + "\n"
                + "layout(location = 1) in vec4 color;" + "\n"
                + "out vec4 vColor;" + "\n"
                + "void main(){" + "\n"
                + "vColor = color;" + "\n"
                + "gl_Position = vec4(position, 0.0, 1.0);" + "\n"
                + "}";
    
        String FRAGMENT = "#version 330 core" + "\n"
                + "in vec4 vColor;" + "\n"
                + "out vec4 fragColor;" + "\n"
                + "void main(){" + "\n"
                + "fragColor = vColor;" + "\n"
                + "}";
    
        shaderProgram = new ShaderProgram();
        shaderProgram.attachVertexShader(VERTEX);
        shaderProgram.attachFragmentShader(FRAGMENT);
        shaderProgram.link();
    
        vboBuff = BufferUtils.createFloatBuffer(25000);
    
        // Generate and bind a Vertex Array
        vaoID = glGenVertexArrays();
        glBindVertexArray(vaoID);
    
        // The indices that form the rectangle
        short[] indices = new short[]
        {
            0, 1, 2,  // The indices for the left triangle
            1, 2, 3   // The indices for the right triangle
        };
    
        // Create a Buffer Object and upload the vertices buffer
        vboVertID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vboVertID);
    
        // Point the buffer at location 0, the location we set
        // inside the vertex shader. You can use any location
        // but the locations should match
        glVertexAttribPointer(0, 2, GL_FLOAT, false, 24, 0);
        glVertexAttribPointer(1, 4, GL_FLOAT, false, 24, 8);
        // Create a Buffer Object and upload the colors buffer
    
        // Create a ShortBuffer of indices
        ShortBuffer indicesBuffer = BufferUtils.createShortBuffer(indices.length);
        indicesBuffer.put(indices).flip();
    
        // Create the Element Buffer object
        eboID = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_STATIC_DRAW);
    
        // Enable the vertex attribute locations
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
    
        glBindVertexArray(0);
    }
    
    public void bind(){
        vboBuff.clear();
        glBindVertexArray(vaoID);
        shaderProgram.bind();
        nrOfVert = 0;
    }
    
    public void render(float x1, float x2, float y1, float y2, Color top, Color bottom){
    
        vboBuff.put(x1).put(y1);
        vboBuff.put(top.r).put(top.g).put(top.b).put(top.a);
        vboBuff.put(x2).put(y1);
        vboBuff.put(top.r).put(top.g).put(top.b).put(top.a);
        vboBuff.put(x1).put(y2);
        vboBuff.put(bottom.r).put(bottom.g).put(bottom.b).put(bottom.a);
        vboBuff.put(x2).put(y2);
        vboBuff.put(bottom.r).put(bottom.g).put(bottom.b).put(bottom.a);
    
        nrOfVert += floatsPerQuad;
    }
    
    public void flush(){
    
        vboBuff.flip();
    
        glBindBuffer(GL_ARRAY_BUFFER, vboVertID);
    
        glBufferData(GL_ARRAY_BUFFER, vboBuff, GL_DYNAMIC_DRAW);
    
        glDrawElements(GL_TRIANGLES, nrOfVert, GL_UNSIGNED_SHORT, 0);
    
        glBindVertexArray(0);
        ShaderProgram.unbind();
    }
    
    public void dispose()
    {
        // Dispose the program
        shaderProgram.dispose();
    
        // Dispose the vertex array
        glBindVertexArray(0);
        glDeleteVertexArrays(vaoID);
    
        // Dispose the buffer object
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDeleteBuffers(vboVertID);
    
        // Dispose the element buffer object
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glDeleteBuffers(eboID);
    }
    

    }

    因为您已经在评论部分找到了答案,现在正在询问创建一个巨大的索引缓冲区并保持其静态是否有效:

    如果数据不会更改,则应使用GL_STATIC_DRAW声明数组缓冲区。GL_DYNAMIC_DRAW向GPU暗示,您将不断更改缓冲区数据,并使驱动程序以不同方式处理您的数据


    如果您真的担心性能,我建议您考虑使用不同的渲染方法,例如,如果要渲染的四边形相同或仅因颜色或其他原因而不同,则使用实例化。看看这个,用一些方法进行实验。

    好的,我想我找到了罪魁祸首。定义索引时,我需要为要绘制的每个四边形定义一个集合。我认为索引缓冲区会被每个元素重用。所以,我想我只会生成一个巨大的索引缓冲区,并在初始化阶段保持它的静态。这有效吗?