How to MultiThread in JOGL

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

How to MultiThread in JOGL

moeabdol
Dear All,
I have been trying so hard to wrap my head around the multithreading concept in JOGL. I looked into many documentations and it seems to me that every documentation I go through passes me to a next one without me finding a complete and simple code that implements multithreaded rendering.

The program that i'm trying ti implement is simple. Within the class that implement GLEventListener and inside the display() method I have a simple algorithm which is a for loop. Inside the loop am generating random x and y coordinates. What I want to do is draw these points as they are being determined by the random generator to give the viewer a sense of how the points are generated in real-time.

To solve this, I have read documentations on JOGL's website that suggested using GLWindow instead of a JFrame to enable  concurrency. I did that! Moreover, I have created a work class that implements a GLRunnable this class includes all the code necessary to do the work of drawing each point following is the content of this class

  1 import javax.media.opengl.GLRunnable;
  2 import javax.media.opengl.GLAutoDrawable;
  3 import javax.media.opengl.GL2;
  4
  5 public class GLWork implements GLRunnable{
  6         private float x;
  7         private float y;
  8         private boolean in;
  9
 10         GLWork(){
 11                 x = 0.0f;
 12                 y = 0.0f;
 13                 in = false;
 14         }
 15
 16         GLWork(float x, float y, boolean in){
 17                 this.x = x;
 18                 this.y = y;
 19                 this.in = in;
 20         }
 21
 22         @Override
 23         public boolean run(GLAutoDrawable drawable){
 24                 GL2 gl = drawable.getGL().getGL2();
 25
 26                 gl.glPointSize(10.0f);
 27                 gl.glPushMatrix();
 28                 gl.glBegin(GL2.GL_POINTS);
 29                         if(in)
 30                                 gl.glColor3f(1.0f, 0.0f, 0.0f);
 31                         else
 32                                 gl.glColor3f(0.0f, 0.0f, 1.0f);
 33                         gl.glVertex3f(x, y, 0.0f);
 34                 gl.glEnd();
 35                 gl.glPopMatrix();
 36
 37                 return true;
 38         }
 39 }

Following I created another work class that implements Runnable and has a private variable of type GLWork. following is the code

1 import javax.media.opengl.GLAutoDrawable;
  2 import javax.media.opengl.GLRunnable;
  3
  4 public class PointWork implements Runnable{
  5         private GLAutoDrawable drawable;
  6         private GLRunnable runnable;
  7
  8         PointWork(){
  9         }
 10
 11         PointWork(float x, float y, boolean in, GLAutoDrawable drawable){
 12                 this.drawable = drawable;
 13                 this. runnable = new GLWork(x, y, in);
 14         }
 15
 16         public void run(){
 17                 synchronized(drawable){
 18                         drawable.invoke(true, runnable);
 19                 }
 20         }
 21 }

Note that I have synchronized the GLAutoDrawable so no other thread can draw on the drawable while this thread is. I'm not really sure if this is the correct way to do it or not.

Now, for the simple algorithm that does the creation of each point and instantiating threads to draw the point. This is inside the display() method.

57                         float x;                                        // x coordinate
 58                         float y;                                        // y coordinate
 59                         boolean in;                                     // true if point is inside circle
 60                         int inCount = 0;                                // counter for points that are in
 61                         float pi;                                       // estimated pi value
 62                         int totalPoints = 1000;                         // total number of random points
 63                         Random floatRandomGenerator = new Random();     // random number generator
 64                         for(int i = 0; i < totalPoints; i++){
 65                                 x = floatRandomGenerator.nextFloat();
 66                                 y = floatRandomGenerator.nextFloat();
 67                                 if((Math.pow(x - 0.5, 2) + Math.pow(y - 0.5, 2)) <= Math.pow(RADIUS, 2)){
 68                                         in = true;
 69                                         inCount++;
 70                                 }
 71                                 else
 72                                         in = false;
 73                                 new Thread(new PointWork(x, y, in, drawable)).start();
 74                         }

The in variable is just to determine if I should draw the point in red or blue.

I hope that my explanation and code is easy to follow and understand, and I hope that someone out there can help me with this issue. Once I understand how to multithread in JOGL I will be able to do many awesome stuff :) thank you
Reply | Threaded
Open this post in threaded view
|

Re: How to MultiThread in JOGL

Sven Gothel
Administrator
On 11/01/2012 12:14 PM, moeabdol [via jogamp] wrote:

> Dear All,
> I have been trying so hard to wrap my head around the multithreading concept
> in JOGL. I looked into many documentations and it seems to me that every
> documentation I go through passes me to a next one without me finding a
> complete and simple code that implements multithreaded rendering.
>
> The program that i'm trying ti implement is simple. Within the class that
> implement GLEventListener and inside the display() method I have a simple
> algorithm which is a for loop. Inside the loop am generating random x and y
> coordinates. What I want to do is draw these points as they are being
> determined by the random generator to give the viewer a sense of how the
> points are generated in real-time.
>
> To solve this, I have read documentations on JOGL's website that suggested
> using GLWindow instead of a JFrame to enable  concurrency. I did that!
> Moreover, I have created a work class that implements a GLRunnable this class
> includes all the code necessary to do the work of drawing each point following
> is the content of this class

Yours is a complicate issue not to easy answer,
since it's not so much about multi threaded rendering
but a multi threaded data provider, which results shall be rendered.

You have to understand how a [A] GPU performs multi threaded rendering,
then how the [B] API copes w/ it .. and may allow you to utilize it.

[A] GPU performs multi threaded rendering:
    One or more threads per fragment (pixel)

[B] No more via the fixed function pipeline (FFP),
    since it only accumulates your immediate mode vertices!
    You would need to use fragment shader to PRODUCE the data
    and 'render' it. The latter is more a 'store the result in framebuffer',
    see [A].

Thanks to another very similar question
  <http://forum.jogamp.org/Multi-Threading-JOGL-Problem-td4026441.html#none>

I gave the same similar answer:
  <http://gamedev.stackexchange.com/a/38576>
  <http://forum.jogamp.org/Re-Muti-Threading-JOGL-Problem-td4026442.html#none>
  <http://forum.jogamp.org/Re-Muti-Threading-JOGL-Problem-td4026443.html>

~Sven


signature.asc (907 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to MultiThread in JOGL

moeabdol
Thank you again Sven for your continuous help. I try to keep up with you're saying, but can only grasp a little at a time. I understand that you can implement this using some customised functions in OpenGL; however, I'm looking for a more general purpose way to implement multi-threaded rendering. This tiny project is an exercise for me so I can learn this aspect of OpenGL. Later I will be using multi-threaded rendering in other applications and don't want a more general understanding so I can apply it in all scenarios.

I know this might be so much, but if you can kindly provide me with simple code that does so, I would be really greatfull. I have looked into the code on JOGL API page - which you have pointed out last time - and tried to follow. I did understand a little bit more, but it didn't seem to get it to work! Thanks :)
Reply | Threaded
Open this post in threaded view
|

Re: How to MultiThread in JOGL

gouessej
Administrator
Hi

You can use the method invoke(boolean,GLRunnable) to post runnables on the OpenGL queue. You can try to make the OpenGL context current on different threads (and release it when you don't need it anymore) but some drivers and/or operating systems might simply not support it and it has a non negligible cost. You can create several shared contexts and use one of them per thread too.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: How to MultiThread in JOGL

moeabdol
Thanks goussej...would you kindly direct me to and example to how to use an OpenGL queue, create a context and make it current for each thread...I understand the theory but can't find a an example out there that practices it. Thank you again for considering my question
Reply | Threaded
Open this post in threaded view
|

Re: How to MultiThread in JOGL

gouessej
Administrator