Pbuffers and graphic cards.

Hello,

I have been playing with pbuffers a little, and I have a few surprises.
I am using pbuffers to draw a texture and then paint it over a square. In the display() method of the gleventlistener added to the pbuffer, I want to write some text, using glutBitmapString. On one pc (p4, radeon r9800), the text is flipped horizontally ( like a mirror). On the other computer (P4, GeForce 440Go) everything is fine.
Another thing. When using the pbuffer as a texture, on the radeon if I do not use pbuffer.releaseTexture(), no problem, on the nvidia, forgetting this causes the jvm to crash.

I am posting here the interesting portions of code, I must be missing something as I a am new to jogl :stuck_out_tongue:

Pbuffer creation :


            if (gl.isExtensionAvailable("WGL_ARB_pbuffer"))
                  System.out.println("pbuffer SUPPORTED");
            else
                  return;
            
            GLCapabilities caps = new GLCapabilities();
            caps.setOffscreenRenderToTexture(true);
            caps.setDoubleBuffered(false);
            
            if (!gLDrawable.canCreateOffscreenDrawable())
            {
                  return;
            }
            
            pbuffer = gLDrawable.createOffscreenDrawable(caps, 512, 512);

            pbuffer.addGLEventListener(new PbufferEventListener());

in the PbufferEventListener display method :


            public void display(GLDrawable drawable)
            {

                  GL gl = drawable.getGL();
                  GLU glu = drawable.getGLU();
            

                  gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
            
            
                  gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
                  gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
      
                  gl.glDisable(GL.GL_DEPTH_TEST);
                  gl.glLoadIdentity();
                  gl.glMatrixMode(GL.GL_PROJECTION);
                  gl.glPushMatrix();
                  gl.glLoadIdentity();      
            
                  glu.gluOrtho2D(0.0, size.x, 0.0, size.y);
                  //gl.glDisable(GL.GL_TEXTURE_2D);
                  //gl.glDisable(GL.GL_LIGHTING);
      
                  
                  gl.glColor3f( 0.3f, 0.3f, 0.7f ); 
                  gl.glLineWidth(5.0f);
                  gl.glBegin (GL.GL_LINE_LOOP);
                        gl.glVertex2i (rpos.x+ret,rpos.y+ret);
                        gl.glVertex2i (rpos.x+size.x-ret,rpos.y+ret);
                        gl.glVertex2i (rpos.x+size.x-ret,rpos.y+size.y-ret);
                        gl.glVertex2i (rpos.x+ret,rpos.y+size.y-ret);
                  gl.glEnd();


                  gl.glRasterPos2i(100,100);
                  glut.glutBitmapString(gl, GLUT.BITMAP_HELVETICA_18, "Some text to test !");


                  //gl.glEnable(GL.GL_TEXTURE_2D);
                  //gl.glEnable(GL.GL_LIGHTING);
                  gl.glPopMatrix();
                  gl.glMatrixMode(GL.GL_MODELVIEW);
                  gl.glEnable(GL.GL_DEPTH_TEST);            

            }

To use the buffer elsewhere :


            pbuffer.bindTexture();
            gl.glBegin(GL.GL_QUADS);
            gl.glColor3f(10f,10f,10f);
            gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex2f(0f,0f);
                  gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex2f( size.x,0f);
                  gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex2f( size.x, size.y);
                  gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex2f(0.0f, size.y);
            gl.glEnd();
            pbuffer.releaseTexture();

I can’t think of a reason why your text would be flipped left-to-right on one card and not another. Do you initialize your texture matrices to the identity matrix?

Do you have a small test program that illustrates the problem? If so, could you file a bug using the Issue tracker on the JOGL web page?

Regarding bindTexture()/releaseTexture(), I can believe that some drivers would be more sensitive than others to not having the pbuffer’s texture binding released properly.

I don’t have a small test program yet, I’ll extract the interesting things and build a simple program as soon as possible :slight_smile:

I don’t think the problem of flipped text comes from the texture mapping, if I use texture mapped fonts to replace glutBitmapString, everything works.

So, I have the problem with the following code :


import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import net.java.games.jogl.Animator;
import net.java.games.jogl.DebugGL;
import net.java.games.jogl.GL;
import net.java.games.jogl.GLCanvas;
import net.java.games.jogl.GLCapabilities;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLDrawableFactory;
import net.java.games.jogl.GLEventListener;
import net.java.games.jogl.GLPbuffer;
import net.java.games.jogl.GLU;


public class Viewer implements GLEventListener
{
      private GLPbuffer pbuffer=null;
      private GLCanvas canvas=null;
      private Frame frame;
      
      
      public Viewer()
      {
            frame = new Frame("Test");
            frame.setResizable(false);
            canvas =GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());
            canvas.setGL(new DebugGL(canvas.getGL()));
            //canvas.setNoAutoRedrawMode(true);
            canvas.addGLEventListener(this);
            frame.add(canvas);
            frame.setSize(800, 600);
            final Animator animator = new Animator(canvas);
            frame.addWindowListener(new WindowAdapter()
                        {
                  public void windowClosing(WindowEvent e)
                  {
                        animator.stop();
                        System.exit(0);
                  }
            });
            frame.show();
            animator.start();
      }
      
      public void init(GLDrawable arg0)
      {
            
            GL gl= arg0.getGL();
            GLU glu=arg0.getGLU();

            gl.glShadeModel(GL.GL_SMOOTH);
            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
            gl.glClearDepth(1.0f);
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glDepthFunc(GL.GL_LEQUAL);
            gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
            gl.glEnable(GL.GL_LINE_SMOOTH);
            gl.glHint(GL.GL_LINE_SMOOTH_HINT,GL.GL_DONT_CARE);
            
            if (!gl.isExtensionAvailable("WGL_ARB_pbuffer"))
            {
                  System.out.println("pbuffer NOT SUPPORT");
                  System.exit(-1);
            }

            if (!arg0.canCreateOffscreenDrawable())
            {
                  System.err.println("pbuffers no OffscreenDrawable");
                  System.exit(-1);
            }
            GLCapabilities caps = new GLCapabilities();
            caps.setOffscreenRenderToTexture(true);
            caps.setDoubleBuffered(false);
            pbuffer = arg0.createOffscreenDrawable(caps, 256, 256);
            pbuffer.addGLEventListener(new PbufferListener());
            System.out.println("Run ...");
      }


      public void display(GLDrawable arg0)
      {
            GL gl= arg0.getGL();
            GLU glu=arg0.getGLU();

      
            
            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

            // Setup cam.
            gl.glLoadIdentity();
            glu.gluLookAt(0, 0, -10,0,0,0,0,-1,0);
            
            // Draw inside the pbuffer.
            pbuffer.display();
            
            // Use the pbuffer as a texture
            gl.glEnable(GL.GL_TEXTURE_2D);      
            pbuffer.bindTexture();
            // Map the content of pbuffer over a quad
            gl.glBegin(GL.GL_QUADS);
                  gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex3f(0f,0f,0f);
                  gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex3f( 5.0f,0f,0f);
                  gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex3f( 5.0f, 5.0f,0f);
                  gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex3f(0.0f, 5.0f,0f);
            gl.glEnd();
            
            pbuffer.releaseTexture();      
            gl.glDisable(GL.GL_TEXTURE_2D);
      }


      public void reshape(GLDrawable gLDrawable,int x,int y,int width,int height)
      {
            GL gl = gLDrawable.getGL();
            GLU glu = gLDrawable.getGLU();
            if (height <= 0) 
                  height = 1;
            float h = (float) width / (float) height;
            gl.glViewport(0, 0, width, height);
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity();
            glu.gluPerspective(45.0f, h, 1.0, 100.0);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            
      }
      
      public void displayChanged(GLDrawable arg0, boolean arg1, boolean arg2)
      {
            
      }
      
      
      public static void main (String args[])
      {
            Viewer v = new Viewer();
      }
}

That works with


import net.java.games.jogl.GL;
import net.java.games.jogl.GLDrawable;
import net.java.games.jogl.GLEventListener;
import net.java.games.jogl.GLU;
import net.java.games.jogl.util.GLUT;



public class PbufferListener implements GLEventListener
{
      private GLUT glut = new GLUT();

      public void init(GLDrawable arg0)
      {
            GL gl = arg0.getGL();
            gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
            gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);

      }

      public void display(GLDrawable arg0)
      {
            GL gl = arg0.getGL();
            GLU glu = arg0.getGLU();
            
            // Clear screen, blue
            gl.glClearColor(0, 0.0f, 0.5f, 1);
            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
            
            // Switch to projection and save matrix
            gl.glDisable(GL.GL_DEPTH_TEST);
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glPushMatrix();
            gl.glLoadIdentity();
            
            // Set up 2D
            glu.gluOrtho2D(0.0, 800, 0.0, 600);
            
            // Write something in red
            gl.glColor3f( 1f, 0.0f, 0.0f );
            gl.glRasterPos2i(50,50);
            glut.glutBitmapString(gl, GLUT.BITMAP_HELVETICA_12, "One string test");      
            
            
            // Back modelview and restores matrix
            gl.glPopMatrix();
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glEnable(GL.GL_DEPTH_TEST);
            
      }


      public void reshape (GLDrawable drawable,int x,int y,int width,int height)
      {}


      public void displayChanged(GLDrawable arg0, boolean arg1, boolean arg2)
      {}

}

When running this, I get this on a radeon :

http://jefk.nerim.net/jogl/radeon.jpg

And this on a geforceGO :

http://jefk.nerim.net/jogl/geforceGO.jpg

I have tried also to initialise texture matrix (did you mean gl.glMatrixMode(GL.GL_TEXTURE); gl.glLoadIdentity(); ?)… Changed nothing. Any ideas are welcome :slight_smile:

I came across the same problem using pbuffers in JSR231, but using glCopyTexSubImage2D instead of bind/release texture to produce a texture. My Mobility Radeon 9000 shows everything OK, whereas a Mobility Radeon 9700 and an NVidia GeForce FX5200 shows textures produced using the pbuffer horizontally flipped. Anyone observed similar behaviour? Any workarounds?

Also, I tried to play a little with glPixelZoom(1,-1) to see if pixels will get inverted, and try it on those cards which flipped the texture produced using the pbuffed. The result is that glPixelZoom had an effect only on those cases (mobility Radeon 9000) where texture appeared normally, and it had absolutely no effect on the ones that flipped the texture. Pretty strange…

Do the HWShadowmapsSImple and ProceduralTexturePhysics demos work properly? Those use glCopyTexSubImage2D to move data from a pbuffer to a texture and seem to work properly on both NVidia and ATI hardware that I’ve tested on (and that support the required extensions).