problem with glReadPixels into ByteBuffer on glnxa64

Hi,

I’m running into what seems to be a platform-specific (glnxa64) issue and would appreciate any advice or insight.

In my GLEventListener display() method, I am attempting to use glReadPixels() to read into a ByteBuffer. When I do this the computer completely freezes (requires a hard-reboot) at that call.
If I use an IntBuffer instead (replacing GL.GL_UNSIGNED_BYTE with GL.GL_INT in the glReadPixels call) it works fine.

The ByteBuffer implementation is towards the bottom of this code snippet. Any ideas on what I’m doing wrong?


  public void display( GLAutoDrawable drawable ) {
    GL gl = drawable.getGL();
    System.out.println("display");
    gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();									// Reset The View
    gl.glTranslatef(0.0f,0.0f,-5.0f);

    if (doIntBuf) { // INT buffer implementation
      System.out.println("intbuffer - do red");
      gl.glColor4f( 1.0f, 0.0f, 0.0f, 0.0f );
    }
    else {
      System.out.println("bytebuffer - do blue");
      gl.glColor4f( 0.0f, 0.0f, 1.0f, 0.0f );
    }

    System.err.println("GLError after colorset: " + gl.glGetError() );
    
    gl.glBegin( GL.GL_TRIANGLES );

    gl.glVertex3f( 0.0f, 0.0f, 0.0f );
    gl.glVertex3f( 1.0f, 0.0f, 0.0f );
    gl.glVertex3f( 0.0f, 1.0f, 0.0f );
    gl.glEnd();
    
   
    // Because opengl's origin is the lower left corner and java's origin
    // is the upper right corner that image will be flipped upside down.
    gl.glReadBuffer( GL.GL_FRONT );

    int glStorageFactor = 3; // # elements per pixel
    int glFormat = GL.GL_RGB;
    
    int glStorageType;
    int intPixelBuf[]   = null;
    byte bytePixelBuf[] = null;

    /* force 1 byte alignment */
    gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
    gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1);

    if (doIntBuf) { // INT buffer implementation
      glStorageType = GL.GL_INT;
      intPixelBuf = new int[maxPbufferWidth * maxPbufferHeight * glStorageFactor];
      IntBuffer intBuf = IntBuffer.wrap(intPixelBuf);
      intBuf.rewind();
      gl.glReadPixels( 0, 0, maxPbufferWidth, maxPbufferHeight, glFormat, glStorageType, intBuf);
    }
    else { // BYTE buffer implementation
      glStorageType = GL.GL_UNSIGNED_BYTE;
      bytePixelBuf =  new byte[maxPbufferWidth * maxPbufferHeight * glStorageFactor];
      if (bytePixelBuf == null) {
        System.err.println("failed to allocate byte buffer - exiting");
        System.exit(1); 
      }
      else {
        System.err.println("byte buffer allocated - length " + bytePixelBuf.length);
      }
      ByteBuffer byteBuf = ByteBuffer.wrap(bytePixelBuf);
      byteBuf.rewind();
      gl.glReadPixels( 0, 0, maxPbufferWidth, maxPbufferHeight, glFormat, glStorageType, byteBuf);
    }
...

Note that the code seems to work fine on both win32 and glnx86.
I’ve also tried (without any success)

  • allocating a larger buffer (current allocation size * 4) thinking that it may be an issue with exceeding the allocated space
  • creating the ByteBuffer with BufferUtil.newByteBuffer(maxPbufferWidth * maxPbufferHeight * glStorageFactor)

Thanks in advance,
Rich

This is almost certainly a graphics driver problem. No user program should be able to hang the entire machine. I also don’t see anything obviously wrong though would need a complete test case to tell more definitively. What kind of graphics card do you have? Are you running your vendor’s latest OpenGL drivers?

I did have an outdated NVidia driver. Updating to the latest takes care of it

Thanks!