[JOGL] VBO's not updating

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

[JOGL] VBO's not updating

Al
This post was updated on .
Hi,

First, I apologize for eventually mistakes in english.

I am pretty new in OpenGL and I am creating an interface for creating voxelized object, using JOGL. Basically, we have the object in the middle of the interface, the list of materials to the right and few utilitary thing to the left. This object can be saved in the text format.

For now, I can load a file and display the object using vbo.
 

This is my code to load the object in my VBO's:

<code>
private void loadVoxels(GL2 gl)
        {
                float sizeVoxelX = VoxObject.getVoxelDimensionX()/2;
                float sizeVoxelY = VoxObject.getVoxelDimensionY()/2;
                float sizeVoxelZ = VoxObject.getVoxelDimensionZ()/2;
                int nbX = VoxObject.getNbVoxelX();
                int nbY = VoxObject.getNbVoxelY();
                int nbZ = VoxObject.getNbVoxelZ();
                nbVoxel = nbX*nbY*nbZ;

                /**  Load Vertex in a buffer **/
                vertexArray = Buffers.newDirectFloatBuffer(8*3*nbVoxel);
                for(int i=0;i<nbX;i++)
                {
                        for(int j=0;j<nbY;j++)
                        {
                                for(int k=0;k<nbZ;k++)
                                {
                                        float[] vertex = new float[]{
                                                        sizeVoxelX+(i*sizeVoxelX*2),sizeVoxelY+(j*sizeVoxelY*2),sizeVoxelZ-(k*sizeVoxelZ*2), //0
                                                        -sizeVoxelX+(i*sizeVoxelX*2),sizeVoxelY+(j*sizeVoxelY*2),sizeVoxelZ-(k*sizeVoxelZ*2), //1
                                                        sizeVoxelX+(i*sizeVoxelX*2),sizeVoxelY+(j*sizeVoxelY*2),-sizeVoxelZ-(k*sizeVoxelZ*2), //2
                                                        -sizeVoxelX+(i*sizeVoxelX*2),sizeVoxelY+(j*sizeVoxelY*2),-sizeVoxelZ-(k*sizeVoxelZ*2), //3

                                                        sizeVoxelX+(i*sizeVoxelX*2),-sizeVoxelY+(j*sizeVoxelY*2),sizeVoxelZ-(k*sizeVoxelZ*2), //4
                                                        -sizeVoxelX+(i*sizeVoxelX*2),-sizeVoxelY+(j*sizeVoxelY*2),sizeVoxelZ-(k*sizeVoxelZ*2), //5
                                                        sizeVoxelX+(i*sizeVoxelX*2),-sizeVoxelY+(j*sizeVoxelY*2),-sizeVoxelZ-(k*sizeVoxelZ*2), //6
                                                        -sizeVoxelX+(i*sizeVoxelX*2),-sizeVoxelY+(j*sizeVoxelY*2),-sizeVoxelZ-(k*sizeVoxelZ*2) //7
                                        };
                                        vertexArray.put(vertex);
                                }
                        }
                }
                vertexArray.flip();
               
               **  Load Indices in a buffer **/
                vertexInd = Buffers.newDirectIntBuffer(6*4*nbVoxel);
                for(int i=0;i<nbVoxel;i++)
                {
                        int[] indices = new int[]{
                                        0+(8*i),2+(8*i),3+(8*i), 1+(8*i),

                                        4+(8*i),6+(8*i),2+(8*i), 0+(8*i),

                                        5+(8*i),7+(8*i),6+(8*i), 4+(8*i),

                                        1+(8*i),3+(8*i),7+(8*i), 5+(8*i),

                                        2+(8*i),6+(8*i),7+(8*i), 3+(8*i),

                                        4+(8*i),0+(8*i),1+(8*i), 5+(8*i)
                        };
                        vertexInd.put(indices);
                }
                vertexInd.flip();
       
               **  Load color in a buffer **/
                colorArray = Buffers.newDirectFloatBuffer(8*3*nbVoxel);
                for(int i=0;i<nbVoxel;i++)
                {
                        float[] color= new float[]{
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                                        1,0,0,
                        };
                        colorArray.put(color);
                }
                colorArray.flip();
               
                /******** VBO *********/
                /** The glGenBuffer is done in the init function **/

                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[0]);
                gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexArray.capacity()*Buffers.SIZEOF_FLOAT,vertexArray, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
               
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[1]);
                gl.glBufferData(GL.GL_ARRAY_BUFFER, colorArray.capacity()*Buffers.SIZEOF_FLOAT, colorArray, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
               
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
                gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, vertexInd.capacity()*Buffers.SIZEOF_INT, vertexInd, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
               
                System.err.println(VoxObject.toString());
                vboIsUpToDate=true;
}

<h2>And this is the one to render:
public void display(GLAutoDrawable drawable) {
                // TODO Auto-generated method stub
               
                GL2 gl = drawable.getGL().getGL2();

                camera.look(gl,glu);
                if(!vboIsUpToDate)
                        loadVoxels(gl);
               
                gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);
                gl.glEnable(GL.GL_DEPTH_TEST);
                gl.glUseProgram(program.getProgramId());
               
                gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
                gl.glEnableClientState(GL2.GL_COLOR_ARRAY);
                gl.glEnableClientState(GL2.GL_INDEX_ARRAY);

                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[0]);
                gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[1]);
                gl.glColorPointer(3, GL.GL_FLOAT, 0, 0);
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
               
                gl.glDrawElements(GL2.GL_POINTS, vertexInd.capacity(), GL.GL_UNSIGNED_INT, 0);

                gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
                gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
                gl.glDisableClientState(GL2.GL_INDEX_ARRAY);
               
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
               
                gl.glUseProgram(0);
        }


The shader is a simple one, my problem don't resolve itself by not activating it. And I make, for those wo will notice, my glGenBuffers in the init method.

This is my problem:


You see that ? ==> if(!vboIsUpToDate)
                                  loadVoxels(gl);

It's to update vertices when something changes, like the loading of a new file. Here is the thing: When I loading a new file, my new voxObject is well loaded (I made some Sysout to check) but the animation is not update, I always see the previous object on my screen.

gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[0]);
                gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexArray.capacity()*Buffers.SIZEOF_FLOAT,vertexArray, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
               
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo[1]);
                gl.glBufferData(GL.GL_ARRAY_BUFFER, colorArray.capacity()*Buffers.SIZEOF_FLOAT, colorArray, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
               
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
                gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, vertexInd.capacity()*Buffers.SIZEOF_INT, vertexInd, GL.GL_DYNAMIC_DRAW);
                gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);


I want this last code to update vbo's, but the vbo's seems to be still the same. But why ? I fill them with a new vertex Array with a new size, why I always see the same object ?

For resume, I can't modify VBO's after having filled it a first time.

Someone can help me, please ? I am break my head on this for two days...


EDIT:To precise, my Scene is in a FPSAnimator and the change with a new loading is done like that:


/*** Ask to the user the new file **/
File file = FileChooser.getSelectedFile();

/*** Load the file in the field member VoxelizedSample ***/
loadFile(file.getAbsolutePath());

/*** Give it to the Scene, setting vboIsUpToDate to false ***/
Scene.setNewObject(VoxSample);


Thank you for reading, hope someone will help !
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Xerxes Rånby
Den 2015-06-02 11:05, Al [via jogamp] skrev:
> private void loadVoxels(GL2 gl)
> {
...
>                 vboIsUpToDate=true;
> }
>
> public void display(GLAutoDrawable drawable) {
...
>                 if(!vboIsUpToDate)
>                         loadVoxels(gl);

Check that the type of
vboIsUpToDate is *not* final.
if you change vboIsUpToDate using a different thread then set it to
volatile type.

You also need to set vboIsUpToDate = false;
after you have you have updated VoxObject

Please post complete sourcecode
a Short, Self Contained, Correct (Compilable), Example http://sscce.org/
, preferably inside a git, else there is no way to check that the application work at runtime.
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
Thank you for your reply.

I will post a git url of my project as soon as I can, no problem.

For your ideas, vboIsUpdate is well set to false when I load a new object an it is not a final boolean.

I am a beginner in OpenGL and I don't know if my managment of VBOs is well done, what do you think ?
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
This post was updated on .
Please show us the whole source code. How can we help you if your mistake is elsewhere? You should avoid magic numbers, for example "8 * 3", how can we guess what they are used for?
Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
I know, I'm sorry, I have a problem with gitHub (what a coincidence, especially when I need it...) so I will try with SVN...



Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
You should use directly the direct NIO buffers you create instead of creating temporary arrays just to transfer their contents into the buffers.

As the limit is already set to the capacity, you should call rewind() instead of flip().
Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
In reply to this post by Al
So I can't reach to post in github, I am truly sorry, I hava an error of type "requested URL" and I can't figure out why...

https://services.emi.u-bordeaux.fr/projet/svn/dosivoxinteface/branches/

This is the url to the SVN Depository, hope you will be able to access it. The inconvenient is this is just text... I am sorry for that, if you don't want to lose your time because of that, I'll understand, I would be annoyed too ^^
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
We're here to help you. I'm reading your source code right now.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
In reply to this post by Al
FloatBuffer.wrap() creates an indirect NIO buffer, JOGL will have to create a direct buffer for you under the hood, I don't advise you to do so.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
In reply to this post by Al
You shouldn't store GL instances (you could use one of them even it has become invalid). Rather call GLContext.getCurrentGL().
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
In reply to this post by Al
You should rather call glBufferSubData to modify a buffer without recreating the whole data store. Use glBufferData only the very first time to create them.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
In reply to this post by Al
Where do you call glClear()? You seem to call only glClearDepth and glClearColor.

gl.glClear(GL.GL_COLOR_BUFFER_BIT|GL.GL_DEPTH_BUFFER_BIT)???
Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
In reply to this post by gouessej
Thank you very much for your convern.

I reuploaded some modification you said to me, like:

- not store instances and getCurrentGL() instead ( In TrackingBall, and loadVoxel)
-I remade the function loadVoxel to separete the portion of code call by the init function and the display function (loadVBO and reloadVBO)
-reloadVBO uses glBufferSubData, after suppressing the previous vbo by calling glBufferData with a null pointer.

Is that right ?
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
I call glClear in the TrackingBall, in the method look. Method which control the glulookat function.
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
In reply to this post by Al
Is your VBO updated now? The GL instance is still stored in GLToolBox.

Replace glu = new GLU() by glu = GLU.createGLU(gl) otherwise you will use a GLU instance not capable to use GL2 and you might get some UnsupportedOperationExceptions.
Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
Nope, the update applies on the VoxelizedObject but not on the vbo...

Thanks anyway for pointing out my bad implementation, I don't have the right habit yet.

I keep trying to update and I will let you know about it =)

EDIT: Just a thought, is there any chance that the error comes from my way to manage the animator which render the GLCanvas ? Maybe it is the animator which don't have the uploading...
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
There is something wrong in your way of using animators but it won't fix the update. You create and run 2 animators, look at the constructor of TopLevelInterface, you create one inside it and another one in createJOGLInterface(). It's preferable to have a single GLEventListener and a single animator per canvas instead of over-complicating a simple case.

At first, a simple Animator with v-sync enabled (see GL.setSwapInterval()) would be more reliable than FPSAnimator.

Then, rather follow my dummy example, create the animator bound to the canvas, add a unique GLEventListener into this canvas, add the canvas into its parent, make all necessary Swing/AWT calls and start the animator:
https://gist.github.com/gouessej/3420e2b6f632efdddf98

I wish you will succeed in displaying your voxels at least as good as ours ;)

Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
This post was updated on .
Awesome ! I hope I will too !

Now, My apllications open a blank window and in a menu Project -> Load File, I load my VoelizedObject. Then, the end of the actionPerformed, I instance my animator.

It seems to nothing on the animator is update if the update don't take place at the begginig of the applications, you see ? I can't figure out why...

Do you think it is the problem that Scene is the Canvas And the GLEventListener ? Do I need to change VoxelizedObject to an implements of GLEventLIstener and use the Scene just as Canvas?

I uploaded my changes on the SVN repository. Or I will, you see this post too soon, like 30s after I post it... Whatever =)

EDIT: I forgot to say that I store the indices of the voxel inside a voxel, so I don't have to recalculate it. Same thing to vertices.

Textures

An other thing I want to ask, seeing your screenshot, about textures, I make the most of your help =). How can you use many textures in your shader ? Because shaders manipulates just texCoords right ? If I have all of my voxels in one VBO, I will have some trouble for texturing no ? Will I need to separete Voxel in different VBO's according to textures ?

EDIT AGAIN

if(e.getSource() == Menu.getLoadFile())
                {
                        int returnVal = FileChooser.showOpenDialog(this);
                        if(returnVal == JFileChooser.APPROVE_OPTION)
                        {
                               
                                File file = FileChooser.getSelectedFile();
                                loadFile(file.getAbsolutePath());
                                Scene = new Scene(VoxSample);
                               
                                animator = new Animator(Scene);
                                Scene.addGLEventListener(Scene);
                                this.add(Scene);
                               
                                animator.start();
                                if(animator.isAnimating())
                                        System.err.println("HERE");
                        }
                }

This code runs when I click on the load button of my JFrame;=.
When I run this code that you can see in the repository (maybe not exactly this one but still), nothing is print on the error output, even I started just before. Note that isStarted() doesn't show anything either, and I got no error on the console (except a ugly thing I can't rid of like that "libEGL warning: DRI2: failed to authenticate" )

What do you think about that ?
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

gouessej
Administrator
Don't worry about the very last warning, it probably means that your driver claims to support DRI2 whereas it doesn't.

You can use a GLSL sampler and/or a texture atlas, look at how it is implemented in ArdorCraftAPI.

If I were you, I would start with something more simple and I would add a few things step by step in order to find the culprit. I assume that you will use several instances of VoxelizedObject, then don't modify this class as it shouldn't implement GLEventListener. Your implementation of GLEventListener should contain the whole drawing code or use other classes containing it.

An efficient voxel engine uses some optimizations that are very specific to this kind of rendering, that's why I advise you to look at ArdorCraftAPI even though you won't use it.
Julien Gouesse | Personal blog | Website
Al
Reply | Threaded
Open this post in threaded view
|

Re: [JOGL] VBO's not updating

Al
Yes, I see on the net about the libEGL error so I ignore it, I hope I won't have portability issues because of that.

Ok, I will look at that API !
I hope I would be able to do nice thing with shaders, it would be great. And It is not really a voxel engine like you think. It is for a scientific purpose, an object is right down on a text file with matrices, and my software read that text and represents this objects with voxel, so I don't need much realism, just textures and maybe a bit of lightning would be great =)

I am not done with the JFrame so I let the 3D for now, thank you very much, gouessej.

I eventually repost in that forum when I continue with VBO's updating, I will in that thread when the times comes.

PS: I am really not sur with my english...