From: Mark M. <pat...@lm...> - 2002-02-26 15:52:12
|
Mark, There are two things you have to understand about selection (ie, picking). First, you have to understand how pure OpenGL does picking. The OpenGL "Red" book will have a nice chapter on this subject, and I really recommend that you read that. Second, you have to understand how GL4Java catches the mouse click events for picking. I can give you a brief description below, but you need to do some reading. How OpenGL does picking: When OpenGL is told that the user clicked the mouse in the canvas for the purpose of picking (see below), it has to render the entire scene at that point (or at least render the objects that you intend to be pickable). OpenGL needs to be told where your mouse was during the click, and you define a "hot area" around the mouse cursor (usually 5x5 pixels) by modifying the matrix stack (see "Red" book). When it renders the scene during this particular frame, nothing is drawn on the monitor. Instead every object is drawn in memory only. Do accomplish this you must put OpenGL in picking mode (see "Red" book). OpenGL will generate a list of every object rendered during this picking frame that happened to intersect with the "hot area" around the mouse cursor. Then it returns this list (ie, "hit" list) for you to process. The list is actually a list of integers. The integers correspond to various 'names' (integers not Strings) that you specified immediately before rendering each object during the pick frame. In other words, you tell OpenGL what integer name you choose for each object during the picking frame. (See "Red" book). Finally, you have to parse through the hit list yourself and decide which object you really intended to pick if there are multiple objects. The easiest method is to just get the first object in that Hit list. What you do with that information (ie, the integer name of the picked object) is up to you and your program design at this point. Remember you ONLY need to put OpenGL in picking mode when you intend to do picking. You ONLY need to modify the matrix stack to have the 5x5 pixel hat area when you intend to do picking. And you ONLY have to provide integers names to objects during the frame that you intend to do picking. Otherwise you are wasting time and screwing up your normal render frames. How GL4Java catches a mouse click: You need to make an object that implements the GLEventListener in GL4Java. Then you need to register this event listener with you GLAnimCanvas, or whatever type of Canvas you are using. Your application should know that it is in picking mode (via some GUI mode you are in), and it should perform all the picking work mentioned above upon the next mouse click. Good luck, Mark M "R.M. Logan" wrote: > Hello, > I was wondering if anybody could help, I'm trying to make objects > in my applet window selectable ie. to select a sphere to trigger an > event...so far i've been mostly following tutorials to get where i am..i > have an environment where objects can be placed and then rotated, zoomed > around with the mouse and keys. I know that to select the objects it's > something to do with hits, but so far i'm at a loss. > If anybody could point me in the correct direction that would be great. > Below is the basic structure of my applet, without my attempts so far at > selection, which will begin from mouseclicked and trigger a select(float > x, float y) method, but i'm again not sure about the methods (esp GL) > which are required. Many thanks. > > //Mark Logan > //Selection of objects in an applet window > > import java.applet.*; > import java.awt.*; > import java.awt.event.*; > > //Gl4Java classes..get out of red > > import gl4java.GLContext; > import gl4java.awt.GLAnimCanvas; > import gl4java.utils.textures.*; > > public class Windowt extends Applet { > > renderCanvas canvas = null; > > //Initialise applet > public void init() { > > setLayout(new BorderLayout());//lays applet components out > canvas = new renderCanvas(getSize().width, getSize().height); > canvas.requestFocus(); > add("Center", canvas); > } > > //Begin the applet > > public void start() { > canvas.start(); //Begins canvas animation > } > > public void stop() { > canvas.stop();//stops the canvas > } > > public void destroy() { > canvas.stop(); > canvas.destroy();//destroys canvas > } > > private class renderCanvas extends GLAnimCanvas implements > KeyListener,MouseListener, MouseMotionListener { > > float xrot = 0.0f;//rotation for x and y > float yrot = 0.0f; > > float moveX = 0.0f;//For mouse movements, try as ints > float moveY = 0.0f; > > float x = 0.0f; > float y = 0.0f; > float z = -8.0f; > > public renderCanvas(int w, int h) { > super(w, h); > addKeyListener(this); > addMouseListener(this); > addMouseMotionListener(this); > } > > public void preInit() { > > doubleBuffer = true; > stereoView = false; > } > > public void init() { > > gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);//Clears colour, change > background > gl.glClearDepth(1.0);//Clear depth buffer > gl.glDepthFunc(GL_LESS);//Depth test > gl.glEnable(GL_DEPTH_TEST);//enable test of depth > gl.glShadeModel(GL_SMOOTH);//Smooth colour shading > gl.glMatrixMode(GL_PROJECTION);//Projection matrix > gl.glLoadIdentity();//Resets matrix > glu.gluPerspective(45.0f, > (float)getSize().width/(float)getSize().height, 0.1f, 100f);//Calculate > window aspect ratio > gl.glMatrixMode(GL_MODELVIEW);//Model view matrix > } > > public void destroy() { > cvsDispose();//Destroys GL context > } > > public void reshape(int width, int height) > { > //Might need to change viewport for object selection??? > gl.glViewport(0, 0 , width, height);//Reset viewport & perspective > gl.glMatrixMode(GL_PROJECTION);//select proj matrix > gl.glLoadIdentity();//reset proj matrix > glu.gluPerspective(45.0f, > (float)getSize().width/(float)getSize().height,0.1f, 100.0f);//Aspect > ratio of window > gl.glMatrixMode(GL_MODELVIEW); > } > > public void display() {//Draw to the canvas > //Changing to implement true camera... > if (glj.gljMakeCurrent(true)==false) > return;//Is GL initialised properly > gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//Clears > //screen & depth buffer > gl.glLoadIdentity();//Reset view > //Look at this, pan for keys, just sub letters for numbers > //Think x and z in terms of new camera movements > > gl.glTranslatef(0.0f, 0.0f, z);//Move into environment > gl.glTranslatef(x, 0.0f, 0.0f);//Strafe > gl.glTranslatef(0.0f, y, 0.0f);//Strafe > gl.glRotatef(xrot,0.0f,1.0f,0.0f);//Rotate on x axis > gl.glRotatef(yrot,1.0f,0.0f,0.0f);//Rotate y..swapped > > renderSphereRed(-2.0f, 1.0f, -1.0f);//Wrap bitmaps around > renderSphereBlue(2.0f, 2.0f, 2.0f);//Need morphing operation > renderSphereYellow(2.0f, 4.0f, 5.0f);//?Name convertor needed > > gl.glFlush();//Might not be necessary > > gl.glEnd(); > > glj.gljSwap();//Swap buffers > glj.gljFree(); > } > > > private void renderSphereRed(float x, float y, float z) {//Create > sphere > > gl.glPushMatrix(); > gl.glTranslatef(x,y,z); > > long qobj = glu.gluNewQuadric(); > glu.gluQuadricOrientation(qobj , GLU_OUTSIDE); > glu.gluQuadricNormals(qobj, GLU_SMOOTH); > gl.glColor3f(1.0f,0.0f,0.0f);//Red > glu.gluQuadricTexture(qobj, false); > glu.gluSphere(qobj, 0.4f, 16, 16); > glu.gluDeleteQuadric(qobj); > > gl.glPopMatrix(); > } > > private void renderSphereYellow(float x, float y, float z) > {//Create sphere > > gl.glPushMatrix(); > gl.glTranslatef(x,y,z); > > long qobj = glu.gluNewQuadric(); > glu.gluQuadricOrientation(qobj , GLU_OUTSIDE); > glu.gluQuadricNormals(qobj, GLU_SMOOTH); > gl.glColor3f(1.0f, 1.0f, 0.0f);//Yellow > glu.gluQuadricTexture(qobj, false); > glu.gluSphere(qobj, 0.4f, 16, 16); > glu.gluDeleteQuadric(qobj); > > gl.glPopMatrix(); > } > > private void renderSphereBlue(float x, float y, float z) {//Create > sphere > > gl.glPushMatrix(); > gl.glTranslatef(x,y,z); > > long qobj = glu.gluNewQuadric(); > glu.gluQuadricOrientation(qobj , GLU_OUTSIDE); > glu.gluQuadricNormals(qobj, GLU_SMOOTH); > gl.glColor3f(0.0f, 0.0f, 1.0f);//Blue > glu.gluQuadricTexture(qobj, false); > glu.gluSphere(qobj, 0.4f, 16, 16); > glu.gluDeleteQuadric(qobj); > > gl.glPopMatrix(); > } > > //Required for implementation of mouselistener etc... > public void mouseEntered(MouseEvent e) { > Component comp = e.getComponent(); > > if(comp.equals(this)) { > requestFocus(); > } > } > > public void mouseExited(MouseEvent e) { > } > > public void mousePressed(MouseEvent e) {//Find a way to hide the > mouse pointer > moveX = e.getX();//Take new mouse reading > moveY = e.getY(); > //Selection here > if ((e.getModifiers() & > InputEvent.BUTTON1_MASK)==InputEvent.BUTTON1_MASK) { > //Test for cursor hiding, hand selector > setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); > } > } > public void mouseReleased(MouseEvent e) { > > setCursor( Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); > > } > > public void mouseClicked(MouseEvent e) { > Component comp = e.getComponent(); > if(comp.equals(this)) { > requestFocus(); > } > > } > > public void mouseMoved(MouseEvent e) { > } > public void mouseDragged(MouseEvent e) { > //Reposition, for better format. > //Again, rearrange, put in method for both buttons held down and y > coordinate zoom > //Manual zoom.... > > if ((e.isMetaDown()) & ((e.getModifiers() & > InputEvent.BUTTON1_MASK)==InputEvent.BUTTON1_MASK)) { > setCursor( Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); > > float newMoveY = e.getY();//Need distance for zoom > > //See which feels better for user > z -= newMoveY - moveY; > > //Update method > > moveY = newMoveY; > > } > > //Think about proper camera, might need sin methods... > > else if (e.isMetaDown()) { > setCursor( > Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));//Find correct method > > float newMoveX = e.getX();//Give us new mouse position > float newMoveY = e.getY(); > > xrot -= newMoveX - moveX;//See which feels better for user > yrot -= newMoveY - moveY; > > //Update method > moveX = newMoveX; > moveY = newMoveY; > > } > > > } > > > //Find actionlistener thing in swing book > public void keyTyped(KeyEvent e) { > //Leave keyboard events out, put mouse in > } > public void keyPressed(KeyEvent e) { > > //Ensure initialisation > if (glj.gljMakeCurrent(true)== false) > return; > > switch(e.getKeyCode()) { > case KeyEvent.VK_PAGE_UP: {//Move back with page up > z -=0.5f; > break; > } > case KeyEvent.VK_PAGE_DOWN: {//Move forward with pd > z +=0.5f; > break; > } > //Change position, change to strafe > case KeyEvent.VK_UP:{//height > y -=0.1f; > break; > } > case KeyEvent.VK_DOWN:{//height > y +=0.1f; > break; > }//Give a camera like feel > > // > case KeyEvent.VK_RIGHT:{//pan > x -=0.1f; > break; > } > case KeyEvent.VK_LEFT:{//pan > x +=0.1f; > break; > } > } > glj.gljFree(); > > } > public void keyReleased(KeyEvent e) { > > } > } > } > > _______________________________________________ > gl4java-usergroup mailing list > gl4...@li... > https://lists.sourceforge.net/lists/listinfo/gl4java-usergroup |