Hello,
I'm trying to have an animation with FPS = 50-60 or something like that. I am drawing portion of disks constructed with 3600x128x4 vertex with VBOs for vertex and texture coordinates for time performances. I have a rotation to do at each FPS for those disks that i choice to implements with a "texture rotate" in it spacial coordinates (less data to transfer at each FPS). My problem is that i have a time mesured for : update of the texture buffer (vertex doesn't change) and drawing in display that is around 20 ms BUT can pass to 4 or more times more (80 or 100 ms)... that cause a "freeze" in the animation. The portion of code having this time-difference comportment is : gl.glBindBuffer(GL.GL_ARRAY_BUFFER, GLVertexBuff); // My vertex buffer are allready in the gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); //graphic card memory gl.glBindBuffer(GL.GL_ARRAY_BUFFER, GLTextureBuff); gl.glBufferData(GL.GL_ARRAY_BUFFER, textureBuff.capacity() * Buffers.SIZEOF_FLOAT, textureBuff, GL.GL_DYNAMIC_DRAW); // Transfert of the new texture coordinates gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); // texttureBuff is a java.nio.FloatBuffer //gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); // I don't initialize anymore the VBO pointer because i //do nothing else gl.glDrawArrays(GL2.GL_QUADS, 0, nbreVertex); // Drawing I was thinking on puting it in another thread than AWT (this time differnece is perhaps cause by this thread ?) but i heard it wasn't a stable solution. All ideas or a links will be welcomed ! (If i am here it is because i search a lot but i am not a pro-programmer) Sorry for my english, thx for help, Nico. |
Administrator
|
Hi
This is the expected behavior as you transfer a lot of data. I just hope you don't call glBufferData for each frame, rather use glBufferSubData especially if you need to modify only a subset. If the VBO containing the vertices doesn't change, use GL_STATIC_DRAW.
Julien Gouesse | Personal blog | Website
|
Thx for your response,
unfortunately, I have to call glBufferdata at each frame because all of the disks are turning... Or i think i have to. Thx for Static_draw. I will try it. |
In reply to this post by gouessej
I just verifyed and i allready have made glstaticdraw statement in the initialization of the buffers...
|
Hi,
again with my problem. I tried again to do with a vertex buffer update like this : gl.glBindBuffer(GL.GL_ARRAY_BUFFER, GLVertexBuff); gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexBuff.capacity() * Buffers.SIZEOF_FLOAT, vertexBuff, GL.GL_DYNAMIC_DRAW); gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, GLTextureBuff); gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0); gl.glDrawArrays(GL2.GL_QUADS, 0, nbreVertex); After having updated VertexBuf which is a Float buffer of java. It is worth ! But not a few ! Perhaps it's due to the third coordinate more to transfer... but it is 10 times worth ! Normal for one more coordinate ? I tried a gl.glBufferSubData but i don't understand how to use it just for the 2 first coordinate ? Is it necessary to use IndicesBuffers ? You wil have noted that i am note a porfessional programmer, I don't realize well the quantity of the data that i am trying to animate : 3600*128*4 = 1,8*10^6 vertex or 1,8 MVertex (with texture static)... Is it that much ? Don't the gamers are doing better ? Thanks for all hilightings |
Administrator
|
Data alignment may impact a bit the performance but it is not consistent, it depends on the hardware and the driver.
Yes 1.8 M vertices, this is a lot. For example, the men in recent AAA first person shooters are composed of between 8000 and 16000 vertices, the levels are subdivided into small pieces to avoid sending millions of vertices to the graphics card.
Julien Gouesse | Personal blog | Website
|
Thanks gouessej,
i have success converting my code with indices buffers so i just need the half of vertices (i don't really need 1.8M / 2 Vertices, but i will be good if i'll be able to ; it depends of some parameters that really change the animation). I have an update process of the texture coordinate java buffer that now take a similar time as the display process... After (lot) of research, could someone explain me how it is possible to make a new thread to treat some java operation inside a display method of a glCanvas. I read (and verify) that all opengl preocess are done in te AWT queue (because unstable issues). My problem is to put some classic work (operations) outside this thread. Can i do that normally with a runnable ? Will it be stable (if i manage well the update of data) ? 'I am not very experienced at multithreading. |
OpenGL operations must be on the same thread, so anything with glXXX must happen on the same thread. Anything else can be worked on by another thread, as long as you take care to not share data between threads in an unsafe manner. For example, you can't write to a direct buffer from one thread and read it (upload to the graphics card) from another thread without some locking.
Have a look at the java.util.concurrent package, it handles a lot of the synchronization issues. You could for example use http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html the Future and an Executor. |
Administrator
|
On 12/12/2013 12:37 AM, jmaasing [via jogamp] wrote:
> OpenGL operations must be on the same thread, so anything with glXXX must > happen on the same thread. This is not correct, one GL context can only be current by one thread at a given time. > Anything else can be worked on by another thread, > as long as you take care to not share data between threads in an unsafe > manner. For example, you can't write to a direct buffer from one thread and > read it (upload to the graphics card) from another thread without some locking. > > Have a look at the java.util.concurrent package, it handles a lot of the > synchronization issues. You could for example use > http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html the > Future and an Executor. Our GLContext instance 'makeCurrent' is blocking as well until released by another thread and hence thread safe. We utilize GlueGen's <http://jogamp.org/deployment/jogamp-next/javadoc/gluegen/javadoc/com/jogamp/common/util/locks/LockFactory.html#createRecursiveLock%28%29> ~Sven signature.asc (911 bytes) Download Attachment |
Administrator
|
Some drivers don't support making an OpenGL context current on another thread than the first one on which it has been done, for example on several Intel chipsets under Windows. In this particular case, it's even more limited than what you suggest which is true in the general case.
Julien Gouesse | Personal blog | Website
|
Thanks for your answers,
but i am confuse now like at the beginning :) I don't understand very well the "makecurrent instance" and other things you mentioned. Clearly : is it possible to calculate the update of my synchronized buffer in another thread within the display method of a glcanvas ? Is there particular stuff to do or can i just : new thread / run and synchronize with glSTUFF... ? Thanks for support, Nico. |
Administrator
|
In reply to this post by gouessej
On 12/12/2013 09:58 AM, gouessej [via jogamp] wrote:
> Sven Gothel wrote > On 12/12/2013 12:37 AM, jmaasing [via jogamp] wrote: > > OpenGL operations must be on the same thread, so anything with glXXX must > > happen on the same thread. > This is not correct, one GL context can only be current by one thread at a > given time. > > Some drivers don't support making an OpenGL context current on another thread > than the first one on which it has been done, for example on several Intel > chipsets under Windows. In this particular case, it's even more limited than > what you suggest which is true in the general case. properly if working at all. ~Sven signature.asc (911 bytes) Download Attachment |
Administrator
|
In reply to this post by NicoFrench
I thought about Intel 3000 HD under Windows, I'm not the only one who has had some problems with it. When you use OpenGL, you need a context (GLContext). When you perform some OpenGL calls, your context must be current on the thread performing these calls. You cannot make a single context current on multiple threads at the same time. You have to separate operations requiring a current OpenGL context from the others and then you can execute the operations that don't require it on another thread as long as you use some proper mean to prevent the access to shared data from several threads, only one thread at a time must be allowed to access your buffer.
Julien Gouesse | Personal blog | Website
|
Thanks for clarifying and for the support !
I have put all computations before display in a parallel thread and i use indices buffer (dividing by 2 the number of vertex). I have now allready passed the computation time around 8 ms. I have always inequal time of traitment but it is now passing from 6 to... 60. I hope i will reduce it with a better synchronization (notify/wait) for the use of buffers (for instance i just have synchronised the blocks of use of the buffer). Is it really normal to have this kind of inequal time when using glBufferData ? and also with computational task for java ? Do i have to pass this discussion to "solved" ? See you, thks, Nico. |
In reply to this post by Sven Gothel
My wording was misleading, I meant what you said - i.e. one GL context can't be shared, at the same time, by several threads. I didn't know that Intel chipsets had problems switching threads - every day I learn something new in these forums |
Administrator
|
It is expected when you go beyond the maximum advised size for a VBO. There were some constants useful for that purpose but they have been removed from OpenGL-ES and from OpenGL too (?). Anyway, sometimes, they contained really absurd values :s Actually, I remember that something was done to work around that in JOGL itself and I spent several weeks or months in fixing that in Ardor3D, it had something to do with AWT too, I'm not sure NEWT was concerned.
Julien Gouesse | Personal blog | Website
|
Certainly another stupid question (i say to my student there is no stupid question, only stupid person that stay like this :)
I have data to compute in parallel of jogl and i did it ! My thread updateBuff() wait updateDisplay() before update of the buffer. But i would like that jogl wait updateBuff() to before updateDisplay()... I tried to do it waiting (he is in the thread AWT-EventQueue-2-FPSAWTAnimator-Timer0) and after fixing some bugs i had a frozen window (nothing reactive - even the close button). I tell me it was because i was doing waiting an AWT-Queue... Is it correct ? Is it possible to do waiting the opengl thread ? In other side, i did a print of this status : Threading.isOpenGLThread() ---> false ! ????? I don't understand : my FPSanimator isn't the thread opengl ? Threading.isSingleThreaded() ---> false : i think it's because of my other trhread because i remember that before it was true ? Thanks for all, Nico. |
Back with other questions !
I tried to put all the GL stuff in one dedicated trhead but i have some architecture problems with the GLBuffers pointers... So i will wait answers to my previous question : is it possible ? Do you have an example of code for cooperation between a thread that compute data and JOGL for display ? For my animation, cooperation is done with synchronized nio.buffers. The thread work with array and put them in the nio.Buffers. JOGL do GL stuff and take these buffers and display it. Each thread has to wait the other before and i am trying this synchronisation (in a synchronized block) with : { while(updated) {try { wait;} ....} DO STUFF; updated = true ; notifyAll(); } Is it pertinent. How to do waiting a AWT-EventQueue ? Another question : is there a more precise FPSanimator ? I work at 60FPS and the difference of rate mesured is very apparent in the animation (10 to almost 30 ms). I never saw pertinent answer to this question in the posts. Is it possible to transform or create a more precise animator ? My brain is heating, sorry. Nico. |
Administrator
|
On 12/16/2013 09:44 PM, NicoFrench [via jogamp] wrote:
> > Another question : is there a more precise FPSanimator ? I work at 60FPS and > the difference of rate mesured is very apparent in the animation (10 to almost > 30 ms). I never saw pertinent answer to this question in the posts. Is it > possible to transform or create a more precise animator ? Either use Animator and set gl.setSwapInterval(1) or .. we need one utilizing Platform.currentMicros(), which uses an accurate time source - not System.*. ~Sven signature.asc (911 bytes) Download Attachment |
Is there a more accurate timer than System.nanoTime? That would be great. http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/System.html#nanoTime() |
Free forum by Nabble | Edit this page |