problem with glu.gluUnproject

I got this problem here with glu.gluunproject

my main objective here is load a mesh, and just to draw lines in front of it… the problem is that I cant seems to be able to draw the lines infront of the loaded mesh. It always appear behind the mesh as shown in the picture.

I use glu.gluunproject to get the object coordinates but some how i reaslised that its not working properly.
below is the code for mi to calculate the object coordinate
I do not know what value should I input for z.

Since im trying to draw in front of the mesh, i tried getting the max z value of the mesh. which is 55.74 but den i input this value into the glu.gluunproject, its seems so wrong where the value returned after the converstion is (110.0…).I suppose to be converted to a value abt 1.

public void calObjectCoor(GL gl,float mousex,float mousey,float z) {

    float x = mousex, y = mousey;

    gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
    gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
    gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);

    /* note viewport[3] is height of window in pixels */
    realy = viewport[3] - (int) y - 1;
    //System.out.println("Coordinates at cursor are (" + x + ", " + realy);

    glu.gluUnProject((double) x, (double) realy, z, //
            mvmatrix, 0,
            projmatrix, 0,
            viewport, 0,
            wcoord, 0);
        }

Why are you trying to get the object coordinates? Are you trying to draw the lines onto the teapot? My guess is that when you go to draw the lines, you have your matrices set up incorrectly so that the z values are still behind the teapot. One option is to disable the depth test when you draw your lines and then they’ll show up always.

The Z value is between 0 and 1 which corresponds to depth value. to get it you should do something like this.


gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
gl.glReadBuffer(GL2.GL_FRONT);
FloatBuffer buffer = FloatBuffer.allocate(3);
gl.glReadPixels( mouseX, (int)winY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, buffer);
FloatBuffer worldC2 = FloatBuffer.allocate(3);
float winZ = buffer.get(0);

and use the winZ in your unproject.

this will give you the point on the exact point (not model vertex) you picked on.

or you can project your max point coordinates using gluproject and use this value for your gluproject calls

Some how I don’t quite get what it means…

Below is my display method and my draw stroke method.

Currently i just input a value z to be 3.0 because I do not know what to put.

I’m sorry rsantina, in ur method, gl.glReadPixels( mouseX, (int)winY, 1, 1, GL2.GL_DEPTH_COMPONENT, GL2.GL_FLOAT, buffer);
what is winy?

I use the value of my mouse and eventually my winZ gets 0.0. but before that I had already try letting z to be 0.0 and still the line is behind the teapot…

public void display(GLAutoDrawable drawable) {
GL gl = drawable.getGL();

    gl.glColor3f(1.0f, 0.0f, 0.0f);
   
    this.calObjectCoor(gl,mouse_x,mouse_y,0.0f);

    //Do not clear screen when drawing the stroke, clear otherwise
    if (clearBuf == true) {
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
    }

    //Only initialized the values of the mouse x, y coordindate upon user's mouse click
    // where tmpX and tmpY are temporary holding ground for starting valus X,Y of the stroke
    if (initStartCoord == true) {
        tmpX = (float) wcoord[0];
        tmpY = (float) wcoord[1];
        initStartCoord = false;
    }
     
    
    // Camera
   setCamera(gl, glu, 4);
            
 
    gl.glPushMatrix();
    if (todraw == true) {
        
        this.drawStroke(gl);
    }
    gl.glPopMatrix();

    gl.glPushMatrix();
    gl.glRotated(scene_yaw * rad_to_deg, 0.0, 1.0, 0.0);
    gl.glRotated(scene_pitch * rad_to_deg, 1.0, 0.0, 0.0);


    //Display the Axis when the user clicks on the show Axis button
    if (gridStatus == true) {
        d.drawAxis(gl, false);
    }
    //Sets color to green and draw object
    gl.glColor3f(0.0f, 1.0f, 0.0f);
    model.draw(gl);
   
    gl.glPopMatrix();  
    gl.glFlush();
}

public void drawStroke(GL gl) {

    if (startX == 999f) {
        startX = tmpX;
        startY = tmpY;
    }
    endX = (float) wcoord[0];
    endY = (float) wcoord[1];

    gl.glLineWidth(2.0f);
    
    gl.glBegin(GL.GL_LINE_STRIP);
     
    gl.glVertex3f(startX, startY,3.0f);
    gl.glVertex3f(endX, endY,3.0f);

    startX = endX;
    startY = endY;
    
    gl.glEnd();
    
    gl.glLineWidth(1.0f);
    gl.glFlush();
    
}

hm… sorry…

I actually managed to do it with this:

gl.glDisable(gl.GL_DEPTH_TEST);
this.drawStroke(gl);
gl.glEnable(gl.GL_DEPTH_TEST);

and I have to clear the depth buffer bit.

Although not very sure if its the right way thou…

float winY = (float)viewport.get(3) - (float)mouseY

The mouseX and winY represent the picked point on screen. in the readpixel method im getting retrieving the z value from the buffer. which you can use. Disabling the Depth Test can make errors on the long run cuz ur not getting any coherent model.

sorry rsantina…
Guess im having like tones of problem now.

1st up, I used glu.gluUnproject so that I am able to draw on the canvas using mouse draw event.
Than I use mouse click to just to show where my cursor is at the point of click.
for the picture below…I click on the tip of the tea port. and through the gluUnproject, I get the value for X of roughly 0.37599047216147075.
Then I try to look for the Maximum vertex X value of the teaport model(should be the vertex at the tip of the teapot). it returns me a 1.xxx value… which is no where close to my mouse cursor value. And the maximum value I can click is just only 0.6xxx. Any idea why is this so?

Is X your mouse position?

Meaning is it in eye coordinates or modelview? can you post ur code?

the X refers to the right most vertex’s x coordinate value of the model.

Heres my code:


public void calObjectCoor(GL gl, float mousex, float mousey, float z) {

        float x = mousex, y = mousey;
        gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
        gl.glGetDoublev(GL.GL_MODELVIEW_MATRIX, mvmatrix, 0);
        gl.glGetDoublev(GL.GL_PROJECTION_MATRIX, projmatrix, 0);

        /* note viewport[3] is height of window in pixels */
        realy = viewport[3] - (int) y ;
      

        glu.gluUnProject((double) x, (double) realy, z, //
                mvmatrix, 0,
                projmatrix, 0,
                viewport, 0,
                wcoord, 0);
    }

For z I currently use the value of 0.
After the above method is called I use the wcoor[0] (x coord) and wcoord[1] (y coord) to as parameters to draw my stroke as below.


public void drawStroke(GL gl) {

        if (startX == 999f) {
            startX = tmpX;
            startY = tmpY;
        }
        endX = (float) wcoord[0];
        endY = (float) wcoord[1];
        gl.glLineWidth(2.0f);
        gl.glBegin(GL.GL_LINE_STRIP);
        gl.glVertex3f(startX, startY, 3.0f);
        gl.glVertex3f(endX, endY, 3.0f);
        System.out.println("Line draw at: "+ startX +", "+startY);
        startX = endX;
        startY = endY;

        gl.glEnd();
        gl.glLineWidth(1.0f);
        gl.glFlush();
    }
    

startX and startY are initiallized with tmpX and tmpY, which holds wcoord[0], wcoord[1] upon mouse press.
and to draw the stroke, i use the disable depth test method that you said was not that safe to use…So is there any right way to do that?

Thanks for the help…

why arent u using the coord at Z if you want the stroke to be on the model?

Because Actually Im Ignoring the Z coordinate.When the stroke is drawn… I just assume its on the model… just by comparing the x n y axis, if there are more than 1 identical x,x coordinates, i’ll just take the one one with the sameller z value.
Just consulted a friend of mine.Well it seems to be correct still, I just have to do more testing to make sure.

Anyway my task here is like provide a cut tool. for example if i draw the stroke in the middel of a model say a ball, the ball will than be splitted into 2 differt colours.Is there anyway for mi to fill the faces?? after I had load the model.

Well the most easy way (not that easy) is to have the stroke drawn on the model (ie: use the xyz of wcoord on every mouse drag event) and ignore the ones that are not on the model it self (if the user continue the line outside the model).

Then split the triangles/polygons with the poly line you have now. and color the triangles accordingly :slight_smile:

hi, what do u mean by this line? (ie: use the xyz of wcoord on every mouse drag event)

And also btw, let say from the start I a a vertex list storing all the vertices,

after I do a rotation to the model(using gl.glrotate()), how am I able to update this vertex list?

i mean to keep the depth coord steady equal during the stroke or to take the depth value at each point and if the value gives out of model value ie 0 or 1 to keep the last one.

And u dont need to update the vertex list of the model or the stroke?

If u mean u wanna rotate the model and stroke together do the rotation before drawing both.

well…
btw I’v loaded a mesh onto the scene.Eg: a ball.
Next I draw a line in front of the ball, dividing it into 2 halves.
Then I would like to shade the 2 halves into different colors.

The problem is how am I going to select the vertices of the mesh that are actually under the line? How am I able to retrive the loaded mesh information?Is using glu.gluunproject or glu.gluproject an easier method?