Thread safe lwjgl?

Started by JudoVana, January 04, 2007, 21:53:50

Previous topic - Next topic

JudoVana

Hello,
i'm doing something lke this:a lot of data are laded and then rendered(in main), and because I know what data will be loaded nexttimes, i want to preload them, in the same time the current data are rendered (they are rendered really long time),

I do it in this way:

counter++;     
if (counter==1){                //first van of data is loaded
currentdata=new big3ddata(somewhere)
dataareloaded=false;
thread loader=new thread(){  //crete new thread in which i want to preload an data in background.
nextdata=big3ddata(somewhereelse)//THIS ROW CAST AN ERROR
dataareloaded=true;
}
loader.start()
}else{                     //every other case
while(!dataareloaded){}    //for the case sdata stil are not loaded
currentdata=nextdata;      //udelej prednactena data aktualnimi
dataareloaded=false;
thread loader=new thread(){  //nacti dalsi data v noem vlakne na pozadi
nextdata=big3ddata(everywhere)
dataareloaded=true;
}
loader.start()
}


The render loop is in main class and sometimes(in long period) is called rutine from the upside

But this is not working:((   :

Exception in thread "Thread-4" java.lang.NullPointerException
        at org.lwjgl.opengl.GL11.glGenTextures(GL11.java:1225)
        at myglpokus.GLApp.allocateTexture(GLApp.java:779)
        at myglpokus.GLApp.makeTexture(GLApp.java:812)
        at myglpokus.GLApp.makeTexture(GLApp.java:792)
        at myglpokus.UnsplitedFoto.<init>(UnsplitedFoto.java:136)
        at myglpokus.Main$2.run(Main.java:2097)
        at java.lang.Thread.run(Thread.java:595)


here are codes from small rutines(in error order;):

    public static int allocateTexture()
    {
        IntBuffer textureHandle = allocInts(1);
        GL11.glGenTextures(textureHandle);
        return textureHandle.get(0);
    }


  public static int makeTexture(ByteBuffer pixels, int w, int h)
    {
        // get a new empty texture
        int textureHandle = allocateTexture();
        // 'select' the new texture by it's handle
        GL11.glBindTexture(GL11.GL_TEXTURE_2D,textureHandle);
        // set texture parameters
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); //gl11.gl_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); //gl11.gl_NEAREST);
        // Create the texture from pixels
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, w, h, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, pixels);
        return textureHandle;
    }

public static int makeTexture(GLImage textureImg)
    {
        if ( textureImg == null ) {
            return 0;
        }
        else {
            return makeTexture(textureImg.pixelBuffer, textureImg.w, textureImg.h);
        }
    }


and this is an row from UnsplitedFoto constructor :136, where it all begun:
texturedata = Main.makeTexture(textureImg);


*************
I think it will be good o highlite that I'm loading  the data in constructor. And i make all posible opertions here ( loading buffered image, changing him, creating an texture , mip mappin, rottating
*****
while the  big3ddata(...) was in main thread all works fine (only when the data changed the scene frozen for (more then)wev seconds(!)
*****
and the last hint: whan i change loader.start() to loader.run() all work but the freezing was here again....
*****
I will be glad for every idea


cornholio

All OpenGL calls must be made in the thread in which its context is current.
At the most simple usage this means creating the display in the main thread and keeping all OpenGL calls in this thread.
If you want to use OpenGL in another thread then you can either create the display in that thread to start with, or use
Display.makeCurrent() (and watch for the usual threading issues, like interrupting a set of drawing commands you might
be in the middle of).


^ from the LWJGL-Wiki: http://lwjgl.org/wiki/doku.php/lwjgl/faq?s=thread#threading

your loader can't allocate a new texture via GL11.glGenTextures unless it
grabs the OpenGL-context with makeCurrent(). but if it does so it will sure
interfere with your rendering thread unless you synchronize them in some way...

JudoVana

hmm not good:(
But i will do my best;)

JudoVana

I have fought with this problem and i won;)
But i do not understand why ogl needs single thread application...:(

cornholio

imagine this:

1. thread.A has created the display and loaded the first dataset
2. it happily renders the textured dataset with texture.A
3. now thread.B needs to allocate a texture for loading the second dataset
4. say it manages to allocate texture.B

see what happens ? now texture.B is the 'currently selected' texture. any
triangles that thread.A is painting now would suddenly have texture.B
assigned instead of texture.A - oh dear ...

1. thread.B has to call makeCurrent() before it can do any GL-stuff
2. thread.A should not do any GL-stuff after thread.B has called makeCurrent()
3. thread.A needs to call makeCurrent() after thread.B is done doing GL-stuff

only one thread is allowed to do GL-stuff at a time
and it needs to call makeCurrent() before it can do so.

i hope that helped...  ::)


JudoVana