Trying to implement picking using the color based approach - render each unique object's primitives as a unique color. Disable autoswap of the component, then when picking render the unique colors to the back buffer and use glReadPixels of the back buffer to get the color under the mouse without swapping the buffer. The issue arises when I use a Swing GLJPanel - the back buffer gets rendered during the picking phase eg the unique colors are rendered onto the JPanel (rather than rendered to the back buffer and not seen again).
JOGL 2.3.1, Windows 7 Demo below with triangle (click on the triangle as see the green picking color). Any ideas? FWIW this works with a GLCanvas, but would very much like to avoid using a heavyweight component in my application import java.awt.Color; import java.awt.Dimension; import java.awt.DisplayMode; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import java.lang.reflect.InvocationTargetException; import java.nio.FloatBuffer; import javax.swing.JFrame; import javax.swing.SwingUtilities; import com.jogamp.opengl.GL2; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLEventListener; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.awt.GLJPanel; /** * Demo program to demonstrate clearing upon rotation * @author Greg Cope * */ public class SwingJOGLRotationClear implements GLEventListener { final GLProfile profile = GLProfile.get( GLProfile.GL2 ); GLCapabilities capabilities = new GLCapabilities( profile ); { capabilities.setDoubleBuffered(true); capabilities.setSampleBuffers(true); capabilities.setFBO(true); } // The canvas final GLJPanel glcanvas = new GLJPanel( capabilities ){ @Override public void swapBuffers(){ //Log when buffers are swapped System.out.println("Swapping buffers"); super.swapBuffers(); } }; private Point mouseDownPoint = null; public static DisplayMode dm, dm_old; private float rquad = 0.0f; private volatile boolean picking = false; private MouseEvent pickingEvent = null; private int glWidth = -1; private int glHeight = -1; @Override public void display( GLAutoDrawable drawable ) { System.out.println("Rendering: " + picking); final GL2 gl = drawable.getGL().getGL2(); gl.glMatrixMode( GL2.GL_MODELVIEW ); gl.glLoadIdentity(); gl.glClearColor(0f, 0f, 0f, 0f); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT ); gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_DEPTH_TEST); gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_LIGHT0); gl.glEnable(GL2.GL_NORMALIZE); gl.glDisable(GL2.GL_CULL_FACE); float[] position = new float[]{0f,0f,50f,0f}; float[] ambient = new float[]{ 0.1f,0.1f,0.1f,0f}; float[] diffuse = new float[]{ 0.9f,0.9f,0.9f,0f }; float[] specular = new float[]{ 0.5f,0.5f,0.5f,0f }; gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, position, 0); gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, 0); gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse, 0); gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, specular, 0); float[] spec = new float[]{1f,1f,1f}; gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, spec, 0); gl.glMaterialf(GL2.GL_FRONT, GL2.GL_SHININESS, 100); gl.glEnable(GL2.GL_LIGHTING); if ( picking ){ System.out.println("drawing to back buffer"); gl.glDrawBuffer(GL2.GL_BACK); gl.glDisable(GL2.GL_LIGHTING); gl.glColor3f(0f,1f,0f); }else{ gl.glColor3f(1f,0f,0f); } float z = -1.5f; gl.glTranslated(0, 0, z); gl.glRotatef(rquad, 0f, 1f, 0f);//1.0f, 1.0f, 1.0f); gl.glTranslated(0, 0, -z); float[] mat = new float[]{1f,0,0,1f}; gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, mat, 0); gl.glNormal3f(0,0,1); gl.glBegin(GL2.GL_TRIANGLES); gl.glVertex3f(-1f, 0, z); gl.glVertex3f(0f,1f, z); gl.glVertex3f(1f,0f,z); gl.glEnd(); if ( picking ){ System.out.println("Picking from back buffer");; FloatBuffer pixels = FloatBuffer.allocate(4); gl.glReadBuffer(GL2.GL_BACK); gl.glReadPixels(pickingEvent.getX(), glHeight - pickingEvent.getY(), 1, 1, GL2.GL_RGBA, GL2.GL_FLOAT, pixels); Color color = new Color(pixels.get(0), pixels.get(1), pixels.get(2)); System.out.println("Pickied color: " + color); picking = false; }else{ drawable.swapBuffers(); } } @Override public void dispose( GLAutoDrawable drawable ) { } @Override public void init( GLAutoDrawable drawable ) { glcanvas.setAutoSwapBufferMode(false); final GL2 gl = drawable.getGL().getGL2(); gl.glShadeModel( GL2.GL_SMOOTH ); gl.glClearColor( 0f, 0f, 0f, 0f ); gl.glClearDepth( 1.0f ); gl.glShadeModel( GL2.GL_SMOOTH ); gl.glEnable( GL2.GL_DEPTH_TEST ); gl.glDepthFunc( GL2.GL_LEQUAL ); gl.glHint( GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST ); } @Override public void reshape( GLAutoDrawable drawable, int x, int y, int width, int height ) { final GL2 gl = drawable.getGL().getGL2(); if( height <= 0 ) height = 1; glWidth = width; glHeight = height; gl.glViewport( 0, 0, width, height ); gl.glMatrixMode( GL2.GL_PROJECTION ); gl.glLoadIdentity(); gl.glFrustum(-1, 1, -1, 1,1, 100); } public static void main( String[] args ) throws InvocationTargetException, InterruptedException { SwingUtilities.invokeAndWait(new Runnable(){ @Override public void run() { final SwingJOGLRotationClear demo = new SwingJOGLRotationClear(); demo.glcanvas.setAutoSwapBufferMode(false);//disable auto swap /* * Listeners for draggin */ demo.glcanvas.addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent e){ demo.mouseDownPoint = e.getPoint(); demo.pickingEvent = e; } @Override public void mouseClicked(MouseEvent e){ demo.picking = true; demo.glcanvas.repaint(); } }); demo.glcanvas.addMouseMotionListener(new MouseMotionAdapter(){ @Override public void mouseDragged(MouseEvent e){ demo.rquad += demo.mouseDownPoint.getX() - e.getX(); demo.mouseDownPoint = e.getPoint(); demo.glcanvas.repaint(); } }); demo.glcanvas.addGLEventListener( demo ); demo.glcanvas.setPreferredSize( new Dimension(400, 400) ); final JFrame frame = new JFrame ( "Demo" ); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add( demo.glcanvas ); frame.setSize( frame.getContentPane().getPreferredSize() ); frame.setVisible( true ); } }); } } |
Administrator
|
Hey
Please use JOGL 2.3.2 as we maintain only the latest version. I'm not sure that you can work around this issue. Please use the system property jogl.gljpanel.noglsl very early. By the way, the color picking doesn't work on computers using emulated palettes.
Julien Gouesse | Personal blog | Website
|
Thanks for the advice. I've moved to the latest version (same issue). Thus far, couldn't come up with a workaround. As a result, I've implemented another picking method in place of the color approach that relies on conversion of screen to world coordinates. So far works
|
Free forum by Nabble | Edit this page |