Speeding the display

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Speeding the display

Dex55
Hello,
I am speeding the display of animations in a java application that simulate the evolution of a plant cells in 3D dimensions .the cells are the elements of an octree. Each cell is a cube with 4 possibles colors . I'm using VBO. The thing is that the refreshing of the view is made every unity of cycles ( determined by the user ) and every unity of cycles for example 5 the cache ( containing the cells ) is sent to the GPU in order to display the new model ( cells are added in every cycle based on the modele of evolution the user choose ) so every cycle the cache gets more big leading to slowing the display in a lot of cases . I have been thinking that i can send only the new celles created in the last unity of cycles to the GPU but then how to display the old ones once the refresh is made ?

here is the code responsable for updating the VBO :

private void updateBuffers(GL2 gl) {
               
                /**
                     * Cache is used as intermediate between a {@link NTree} and a OpenGL
                     * manager to convert model data in {@link CellQuadBuffer}s to be used by OpenGL
                      * drawing methods.
             */
                synchronized (cache) {
                        minPoint = (cache.getMinPoint() == null)? new Vector3d() : new Vector3d(cache.getMinPoint());
                        maxPoint = (cache.getMaxPoint() == null)? new Vector3d() : new Vector3d(cache.getMaxPoint());

                        int[] gpuBuffers;
                       /**
                        * CellQuadBuffer stores {@link Cell}s in {@link Buffer}s and in a format usable by
                       * OpenGL.
                       * <p>
                       * {@link Cell}s are represented to match the OpenGL GL_QUADS primitive shape,
                       * with their unique color. </br> The outlines color of a cube is the inverse of
                       * the color of this cube (except that the alpha value is the same).
                       */
                        List<CellQuadBuffer> oldList = listBuffers;
                        listBuffers = new ArrayList<>(cache.getCellBuffers());

                        Buffer vertices, colors, outlinesColors, indices;

                          if (vboEnabled) {
                                for (CellQuadBuffer cb : oldList) {
                                        // delete existing buffers
                                        gpuBuffers = new int[] { cb.gpuBufferVertices, cb.gpuBufferColors, cb.gpuBufferIndices,
                                                        cb.gpuBufferOutlinesColors };

                                        gl.glDeleteBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                                }

                                oldList.clear();

                                for (CellQuadBuffer cb : listBuffers) {

                                        // generate new buffers
                                        gpuBuffers = new int[] { cb.gpuBufferVertices, cb.gpuBufferColors, cb.gpuBufferIndices,
                                                        cb.gpuBufferOutlinesColors };

                                        gl.glDeleteBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                   
                   
                                        gl.glGenBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                                       
                                        cb.gpuBufferVertices = gpuBuffers[0];
                                        cb.gpuBufferColors = gpuBuffers[1];
                                        cb.gpuBufferIndices = gpuBuffers[2];
                                        cb.gpuBufferOutlinesColors = gpuBuffers[3];

                                        vertices = cb.getVertices();
                                        colors = cb.getColors();
                                        outlinesColors = cb.getOutlinesColors();
                                        indices = cb.getIndices();

                                        // vertex buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, cb.gpuBufferVertices);
                                        gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices.capacity() * Buffers.sizeOfBufferElem(vertices), vertices,
                                                GL.GL_STATIC_DRAW);

                                        // color buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, cb.gpuBufferColors);
                                    gl.glBufferData(GL.GL_ARRAY_BUFFER, colors.capacity() * Buffers.sizeOfBufferElem(colors), colors,
                                                        GL.GL_STATIC_DRAW);

                                        // outlines color buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, cb.gpuBufferOutlinesColors);
                                        gl.glBufferData(GL.GL_ARRAY_BUFFER, outlinesColors.capacity() * Buffers.sizeOfBufferElem(outlinesColors),
                                                        outlinesColors, GL.GL_STATIC_DRAW);

                                        // indices buffer
                                        gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, cb.gpuBufferIndices);
                                        gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.capacity() * Buffers.sizeOfBufferElem(indices), indices,
                                                        GL.GL_STATIC_DRAW);

                                        cb.resetBuffer();
                                }
                        }

                        cache.resetData();
                        cache.dataUsed();
                }
        }


Thank you .
Reply | Threaded
Open this post in threaded view
|

Re: Speeding the display

gouessej
Administrator
Hi

The synchronization might cause noticeable slowdowns. You should follow the advises I gave you on StackOverflow. Use glBufferSubData or glMapBufferRange to update only a part of your VBO, the performance depends on the hardware.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Speeding the display

Dex55
Hi ,

I tried to modify the code and use glBufferSubData but when i run nothing is drawed . In my code the cells are stored into a list of buffers ( created in Class cache) every buffer contains 4 principla attributs (vertices , colors , outline colors , indices ) each buffer contains stores many cells . the original code of the method UpdateBuffers is sending every time the contents of each buffer from the list to the gpu with GlBufferData ( used 4 times ; one time for each attribut of the buffer ) . I thought i can create from the begining one big space for every attribute ( vertices , colors , outline colors , indices ) with GLBuffer data and then use GLBufferSubData to send just the new cells to the GPU . Here is my code for the method : updateBuffers
----------
private void updateBuffers(GL2 gl) {
                synchronized (cache) {
                        minPoint = (cache.getMinPoint() == null)? new Vector3d() : new Vector3d(cache.getMinPoint());
                        maxPoint = (cache.getMaxPoint() == null)? new Vector3d() : new Vector3d(cache.getMaxPoint());

                        int[] gpuBuffers;
                        List<CellQuadBuffer> oldList = listBuffers;
                        listBuffers = new ArrayList<>(cache.getCellBuffers());

                        Buffer vertices, colors, outlinesColors, indices;

                          if (vboEnabled) {
                                for (CellQuadBuffer cb : oldList) {
                                        // delete existing buffers
                                        gpuBuffers = new int[] { cb.gpuBufferVertices, cb.gpuBufferColors, cb.gpuBufferIndices,
                                                        cb.gpuBufferOutlinesColors };

                                        gl.glDeleteBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                                }

                                oldList.clear();

                                for (CellQuadBuffer cb : listBuffers) {
                                       
                                            if (i==0)
                                            {
                                                // generate new buffers
                                                gpuBuffers = new int[] { 0,1, 2, 3 };

                                                gl.glDeleteBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                                               
                                                gl.glGenBuffers(CellQuadBuffer.NUMBER_OF_BUFFERS, IntBuffer.wrap(gpuBuffers));
                                               
                                                cb.gpuBufferVertices = gpuBuffers[0];
                                                cb.gpuBufferColors = gpuBuffers[1];
                                                cb.gpuBufferIndices = gpuBuffers[2];
                                                cb.gpuBufferOutlinesColors = gpuBuffers[3];
                                       
                                            }
                                       
                                        vertices = cb.getVertices();
                                        colors = cb.getColors();
                                        outlinesColors = cb.getOutlinesColors();
                                        indices = cb.getIndices();

                                        // vertex buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
                                        if (i==0)
                                        {
                                               
                                        gl.glBufferData(GL.GL_ARRAY_BUFFER, vertices.capacity() * Buffers.sizeOfBufferElem(vertices)*10, vertices,
                                                GL.GL_STATIC_DRAW);
                                        offsetPosition1 = vertices.capacity() * Buffers.sizeOfBufferElem(vertices);
                                        }
                                       
                                        else
                                        {
                                               
                                                gl.glBufferSubData(GL.GL_ARRAY_BUFFER,offsetPosition1, vertices.capacity() * Buffers.sizeOfBufferElem(vertices), vertices);
                                                offsetPosition1 = offsetPosition1 + vertices.capacity() * Buffers.sizeOfBufferElem(vertices);
                                        }
                   
                                       
                                        // color buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 1);
                                        if (i == 0)
                                        {
                                    gl.glBufferData(GL.GL_ARRAY_BUFFER, colors.capacity() * Buffers.sizeOfBufferElem(colors)*10, colors,
                                                        GL.GL_STATIC_DRAW);
                                    offsetPosition2 = colors.capacity() * Buffers.sizeOfBufferElem(colors);
                                        }
                                        else
                                        {
                                                gl.glBufferSubData(GL.GL_ARRAY_BUFFER,offsetPosition2, colors.capacity() * Buffers.sizeOfBufferElem(colors), colors);
                                                offsetPosition2 = offsetPosition2 + colors.capacity() * Buffers.sizeOfBufferElem(colors);
                                        }
                                        // outlines color buffer
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 2);
                                        if (i == 0)
                                        {
                                        gl.glBufferData(GL.GL_ARRAY_BUFFER, outlinesColors.capacity() * Buffers.sizeOfBufferElem(outlinesColors)*10,
                                                        outlinesColors, GL.GL_STATIC_DRAW);
                                        offsetPosition3 = outlinesColors.capacity() * Buffers.sizeOfBufferElem(outlinesColors);
                                        }
                                        else
                                        {
                                                gl.glBufferSubData(GL.GL_ARRAY_BUFFER,offsetPosition3, outlinesColors.capacity() * Buffers.sizeOfBufferElem(outlinesColors),
                                                                outlinesColors);
                                                offsetPosition3 = offsetPosition3 + outlinesColors.capacity() * Buffers.sizeOfBufferElem(outlinesColors);
                                               
                                        }
                                        // indices buffer
                                        gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 3);
                                        if (i== 0)
                                        {
                                        gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.capacity() * Buffers.sizeOfBufferElem(indices)*10, indices,
                                                        GL.GL_STATIC_DRAW);
                                        offsetPosition4 = indices.capacity() * Buffers.sizeOfBufferElem(indices);
                                        i=1;
                                        }
                                       
                                        else
                                        {  
                                                gl.glBufferSubData(GL.GL_ELEMENT_ARRAY_BUFFER,offsetPosition4, indices.capacity() * Buffers.sizeOfBufferElem(indices), indices);
                                                System.out.println("ici");
                                                offsetPosition4=offsetPosition4 + indices.capacity() * Buffers.sizeOfBufferElem(indices);
                                        }
                                        cb.resetBuffer();
                                }
                        }

                        cache.resetData();
                        cache.dataUsed();
                }
        }

==============
And this is the code responsible for the drawing :

public void display(GLAutoDrawable gLDrawable) {
                long start = System.nanoTime();
                int nbIndicesTotal=0;

                GL2 gl = gLDrawable.getGL().getGL2();

                if (cache.isDataChanged()) {
                        updateBuffers(gl);
                }

                // erase display and clear buffers
                gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

                gl.glLoadIdentity();

                gl.glMultMatrixd(camera.getViewCopy(), 0);

                // Transparence
                if (transparencyEnabled) {
                        gl.glDisable(GL.GL_DEPTH_TEST);
                        gl.glEnable(GL.GL_BLEND);
                } else {
                        gl.glEnable(GL.GL_DEPTH_TEST);
                        gl.glDisable(GL.GL_BLEND);
                }

                if (drawDebug) {
                        drawReferenceAxes(gl);
                        drawCubeEdges(gl, minPoint, maxPoint);
                }

                // enable and specify pointer to vertex and color array
                gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
                gl.glEnableClientState(GLPointerFunc.GL_COLOR_ARRAY);

                //Buffer vertices, colors, outlinesColors, indices;
     
        for (CellQuadBuffer cb : listBuffers)
       
                 {
        nbIndicesTotal = nbIndicesTotal + cb.getNbIndices() ;
                 }
                        if (vboEnabled) {
                                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
                                gl.glVertexPointer(CellQuadBuffer.NB_COORDINATES_PER_VERTEX, GL.GL_FLOAT, 0, 0);

                                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 1);
                                gl.glColorPointer(CellQuadBuffer.NB_COLORS_PER_VERTEX, GL.GL_UNSIGNED_BYTE, 0, 0);

                                // Link the buffer
                                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 3);

                                gl.glDrawElements(GL2.GL_QUADS, nbIndicesTotal, GL.GL_UNSIGNED_INT, 0);

                                if (outlineVisible) {
                                        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 2);
                                        gl.glColorPointer(CellQuadBuffer.NB_COLORS_PER_VERTEX, GL.GL_UNSIGNED_BYTE, 0, 0);

                                        gl.glDrawElements(GL2.GL_LINES, nbIndicesTotal, GL.GL_UNSIGNED_INT, 0);
                                }

                        } /*else {
       

                                if (cb.getVertices().capacity() > 0) {
                                        // Vertex arrays
                                        gl.glVertexPointer(CellQuadBuffer.NB_COORDINATES_PER_VERTEX, GL.GL_FLOAT, 0, cb.getVertices());
                                        gl.glColorPointer(CellQuadBuffer.NB_COLORS_PER_VERTEX, GL.GL_UNSIGNED_BYTE, 0, cb.getColors());

                                        gl.glDrawElements(GL2.GL_QUADS, cb.getIndices().capacity(), GL.GL_UNSIGNED_INT, cb.getIndices());

                                        if (outlineVisible) {
                                                gl.glColorPointer(CellQuadBuffer.NB_COLORS_PER_VERTEX, GL.GL_UNSIGNED_BYTE, 0, cb.getOutlinesColors());

                                                gl.glDrawElements(GL2.GL_LINES, cb.getIndices().capacity(), GL.GL_UNSIGNED_INT, cb.getIndices());
                                        }
                                }
                        }*/
               
       
       
       

                // disable vertex and color arrays after drawing
                gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
                gl.glDisableClientState(GLPointerFunc.GL_COLOR_ARRAY);

                gl.glFlush();

                fireDisplayUpdated();

                if (debug) {
                        Logger.getGlobal().finest("total time for display(): " + (System.nanoTime() - start) / 1000 + "µs");
                }
        }
======================
i hope you can help me , i'm really stuck here . Thank you for your replies and time .
Reply | Threaded
Open this post in threaded view
|

Re: Speeding the display

gouessej
Administrator
Have you even succeeded in using glBufferSubData on a simple example first?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Speeding the display

Dex55
I didn't use it myself but i saw a few examples and read the documentation about how it works . i'm really pressed for time and i believe the code i put should work but i don't understand why nothing is displayed . i'll really appreciate any help , thanks .