Mystery problem with JOGL using display lists and texturing

I’m lost…the attached programs blow up with an unexpected error in the Java runtime. If I take out either the texture related commands OR the display list handling - it works. Similar code works in c#/OpenTK and pyOpenGL. I will attach both program files…but the relavant code will follow (just an ugly example):

    public void display(GLAutoDrawable drawable) {

        System.err.println("display");
        GL gl = drawable.getGL();

        // Clear the drawing area
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        // Reset the current matrix to the "identity"
        gl.glLoadIdentity();

        // Move the "drawing cursor" around
        gl.glTranslatef(-1.5f, 0.0f, -6.0f);

        if (flag) {

            displaylist = gl.glGenLists(1);
            gl.glNewList(displaylist, GL.GL_COMPILE);
            if (texture == null) {
                try {
                    texture = TextureIO.newTexture(new File("C:\\Documents and Settings\\LD003\\My Documents\\Python Projects\\pyBzEdit2\\textures\\wall.png"), false);
                } catch (IOException e) {
                    
                }
                gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
                gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
                texture.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
                texture.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
            }
            texture.enable();
            texture.bind();

            gl.glBegin(GL.GL_TRIANGLES);
            gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);    // Set the current drawing color to white
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex3f(0.0f, 1.0f, 0.0f);   // Top
            gl.glTexCoord2f(-1.0f, -1.0f);
            gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
            gl.glTexCoord2f(1.0f, -1.0f);
            gl.glVertex3f(1.0f, -1.0f, 0.0f);  // Bottom Right
            // Finished Drawing The Triangle
            gl.glEnd();
            texture.disable();
            gl.glEndList();

            gl.glCallList(displaylist);

        } else {
            gl.glCallList(displaylist);
            
        }


        // Move the "drawing cursor" to another position
        gl.glTranslatef(3.0f, 0.0f, 0.0f);
        // Draw A Quad
        gl.glBegin(GL.GL_QUADS);
            gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);    // Set the current drawing color to light blue
            gl.glVertex3f(-1.0f, 1.0f, 0.0f);  // Top Left
            gl.glVertex3f(1.0f, 1.0f, 0.0f);   // Top Right
            gl.glVertex3f(1.0f, -1.0f, 0.0f);  // Bottom Right
            gl.glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
        // Done Drawing The Quad
        gl.glEnd();

        // Flush all drawing operations to the graphics card
        gl.glFlush();
    }

Please use the DebugGL pipeline (see http://download.java.net/media/jogl/builds/archive/jsr-231-1.1.0/jogl-1.1.0-windows-i586/Userguide.html) and post the full console output inclusive the full error message.

I should have mentioned I am using JOGL 1.1.1, Netbeans 6.7 RC2, and Java 6 update 12.

I will attach the console messages and the error report in hopes that they will help. They give me no clues. I can make this all work by simply moving the texture loading outside of the lines where the display list is being compiled. I don’t really want to do this in my ‘real’ application as it forces me to check each object for new textures before drawing it, which adds steps that I have not needed in very similar situations with other toolkits. Let me know if there is anything else I can provide that will help decide if this is a bug or a ‘feature’.

Thanks,

David

should have said JOGL version JSR-231 1.1.1 (windows…the version that is available to download currently).

I suspect that the problem is that the TextureIO performs an operation not permitted in displaylists or is buggy in common drivers. Move the loading of the texture outside of glNewList. Having it inside glNewList makes not much sense, since the loading code won’t be executed in the display list anyway.

Maybe this is even the problem, cause the texture state changes are executed in callList, but the pointer to the texture is null, since the loading code isn’t executed.

[quote]Move the loading of the texture outside of glNewList
[/quote]
that works…but I already knew that. The reason that it is such a pain is that I’m lazy-loading the textures while I draw the ‘faces’ in my objects whenever I find a texture that is not already loaded. I have a work around, but it requires that I ‘pre-scan’ each object for unloaded textures. This results in an extra step and performance decrease that I’d love to avoid. Does TextureIO work on a different thread or make state changes that could cause this?

This is doubly odd to me as really (true confession time), what I am doing is writing a python application. I have a cpython version that uses pyOpengl, an IronPython version that uses OpenTK and the jython version using JOGL. The other two work fine if I load the textures ‘on the fly’ while ‘in’ a glNewList :persecutioncomplex:. I figured that maybe jython was messing something up…but my ugly test program in java does the same exact thing.

Oh well I guess I will live with the issue and just not worry about it. :-\

Thanks,

David

you could try to load the texture manually without JOGL’s texture IO utilities.

I still don’t get it. Why loading a texture in a glNewList() when this step won’t be recorded in the display list anyway. You can only record gl operations in a display list and loading a file clearly isn’t…

I suspect with your code you simply bind a null pointer as a texture, which causes the access violation.

From the Texture class docs:

[i]When creating an OpenGL texture object, the Texture class will attempt to leverage the GL_ARB_texture_non_power_of_two and GL_ARB_texture_rectangle extensions (in that order) whenever possible. If neither extension is available, the Texture class will simply upload a non-pow2-sized image into a standard pow2-sized texture (without any special scaling). Since the choice of extension (or whether one is used at all) depends on the user’s machine configuration, developers are recommended to use getImageTexCoords() and getSubImageTexCoords(int, int, int, int), as those methods will calculate the appropriate texture coordinates for the situation.

One caveat in this approach is that certain texture wrap modes (e.g. GL_REPEAT) are not legal when the GL_ARB_texture_rectangle extension is in use. Another issue to be aware of is that in the default pow2 scenario, if the original image does not have pow2 dimensions, then wrapping may not work as one might expect since the image does not extend to the edges of the pow2 texture. If texture wrapping is important, it is recommended to use only pow2-sized images with the Texture class.
[/i]
and

For best performance, try to avoid calling enable() / bind() / disable() any more than necessary. For example, applications using many Texture objects in the same scene may want to reduce the number of calls to both enable() and disable(). To do this it is necessary to call getTarget() to make sure the OpenGL texture target is the same for all of the Texture objects in use; non-power-of-two textures using the GL_ARB_texture_rectangle extension use a different target than power-of-two textures using the GL_TEXTURE_2D target.

Your use of GL_REPEAT may be a problem if you aren’t specifically disabling the use of the afore-mentioned extensions and/or your textures are non-pow2. You might want to include calls to glGetError and gluErrorString at the end of your rendering loop - it may help your debugging.

While you are right, I think it is unrelated to his problem. Btw. using the DebugGL pipeline will output GL errors for you automatically.

Well, despite limited knowledge about this I got mad at the problem and decided to try manually loading the texture ‘the old fashioned way’ without using TextureIO or even Texture. After not understanding that I needed to ‘rewind’ my ByteBuffer for a little while ??? I managed to get the routine to work. It just loads a texture and hands me back a texture id. After I got the routine to work outside of glNewList I fearfully placed it after the glNewList and…it worked!!!

So my problem is solved. Unfortunately, the mystery is not…but now I’m not sure I care :slight_smile:

I can understand that loading a texture while inside a glNewList is perhaps not a great idea in theory, but it does seem to work…just not with the TextureIO class.

Regards,

David

I will attach the test program’s GLRenderer code…

Ok last post on this topic - I promise…

First, thank you cylab, and bienator for your assistance!

The approach of loading the texture myself was a good step towards making this work. Also the general idea that loading textures in the middle of a glNewList is a BAD THING turned out to be very accurate! While it was working ok for small (256 x 256) png textures, the first time I hit a larger texture I got an access violation…in all three implementations of my program in jython, cpython and IronPython! That forced me to think of a better way to handle this. Now as I load the objects and materials that I’m going to draw into my application I just do a quick check for unloaded textures (instead of each time I draw them)! In the cpython and IronPython versions I just load the unloaded textures. In the jython version I just throw the texture names into a queue and then process the queue in the display method of the listener. This seems to be rock solid and the jython version has very little extra overhead (just checking the queue each time in draw).

Thanks again for the help!

Regards,

David