PDA

View Full Version : Problem using gluPickMatrix with Tao on Visual Basic



bindes1974@libero.it
11-16-2015, 12:42 AM
Hi all, i'm new in this forum and i'm new with OpenGL (and my english is terrible, sorry).
I have a problem using the gluPickMatrix to grab the mouse picked elements in a OpenGL window.
My problem is that the X and Y mouse coordinates i use to define the gluPickMatrix does not match the object correctly, i mean if i pass to the function the real mouse coordinates in the window (X and Height-Y) it works correctly over the center of the window, but not correctly when i click in ln some other parts.
Infact if i want it works almost correctly i have to moltiply X and Y for a certain factor (different between x and y) that i found by attempts.
So, i say "it works almost fine", because when i resize my window and i zoom my view those factors should be corrected... i think because the perspective deformation.

This is the code of the rendering routine:



Public Sub Refresh()

Dim V(3) As Integer

UpdateLights()
Gl.glInitNames()
Gl.glPushName(0)
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT Or Gl.GL_DEPTH_BUFFER_BIT Or Gl.GL_STENCIL_BUFFER_BIT)
Gl.glLoadIdentity()

If GrabSelection = True Then
Gl.glGetIntegerv(Gl.GL_VIEWPORT, V)

'*********************************************
'this is what i have to add to my code:
Dim smx, smy As Double
smx = 12.2
smy = 9.11
Dim dblX As Double = (GrabX - V(2) / 2) * smx + V(2) / 2
Dim dblY As Double = (GrabY - V(3) / 2) * smy + V(3) / 2

'it would be only:
'Dim dblX as Double = CDbl(GrabX)
'Dim dblX as Double = CDbl(GrabX)

'*********************************************

Glu.gluPickMatrix(dblX, dblY, 5, 5, V)
Gl.glRenderMode(Gl.GL_SELECT)
End If

'Rotate system
Gl.glTranslatef(0, 0, -100)
Gl.glTranslatef(Dx, Dy, Dz)
Gl.glRotatef(Ax, 1, 0, 0)
Gl.glRotatef(Ay, 0, 1, 0)
Gl.glRotatef(Az, 0, 0, 1)
Gl.glScalef(Zoom, Zoom, Zoom)

'draw elements on active layers
For I = 0 To UBound(List)
If List(I).Visible = True Then
'draw list
Gl.glPushName(I + 1)
Gl.glCallList(I + 1)
End If
Next

If GrabSelection = True Then
GrabSelection = False
Dim h As Integer = Gl.glRenderMode(Gl.GL_RENDER)
If h > 0 Then ParseBuffer(h)
Gl.glPopMatrix()
Else
'present draw
Gl.glFlush()
Gdi.SwapBuffers(hDC)
End If

End Sub


This sub is called by a timer, and when the user click on the window i set the GrabSelection boolean to TRUE, so one frame is lost but at the end of the rendering i parse the grabbed selectionbuffer.
In the code i indicated the part that puzzles me.
Any idea to solve this problem?
Thanks in advance.

bindes1974@libero.it
12-06-2015, 03:27 AM
No reply... I probably am the only one that try to use OpenGL under VB.net...
I'm continuing to develop my application neglecting this problem, but sooner or later I will have to solve it. Any suggestions?

GClements
12-06-2015, 12:15 PM
Looking at your code, it looks like you're applying the pick matrix to the model-view matrix. It needs to be part of the projection matrix, before any perspective or orthographic projection is applied. E.g. in C:


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix(...);
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
...

bindes1974@libero.it
12-19-2015, 03:56 AM
Looking at your code, it looks like you're applying the pick matrix to the model-view matrix. It needs to be part of the projection matrix, before any perspective or orthographic projection is applied. E.g. in C:


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPickMatrix(...);
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
...


Thanks for the reply!
I tried to change my code like that:


Public Sub Refresh()
Dim V(3) As Integer

Gl.glInitNames()
Gl.glPushName(0)
Gl.glMatrixMode(Gl.GL_PROJECTION)
Gl.glLoadIdentity()
Glu.gluPerspective(10.0#, P.Width / P.Height, 0.1#, 10000.0#)

If GrabSelection = True Then
Gl.glGetIntegerv(Gl.GL_VIEWPORT, V)
Glu.gluPickMatrix(GrabX, GrabY, 5, 5, V)
Gl.glRenderMode(Gl.GL_SELECT)
End If

Gl.glMatrixMode(Gl.GL_MODELVIEW)
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT Or Gl.GL_DEPTH_BUFFER_BIT Or Gl.GL_STENCIL_BUFFER_BIT)
Gl.glLoadIdentity()

'Rotate system
Gl.glTranslatef(0, 0, -100)
Gl.glTranslatef(Dx, Dy, Dz)
Gl.glRotatef(Ax, 1, 0, 0)
Gl.glRotatef(Ay, 0, 1, 0)
Gl.glRotatef(Az, 0, 0, 1)
Gl.glScalef(Zoom, Zoom, Zoom)

'draw elements
For I = 0 To UBound(List)
Gl.glPushName(I + 1)
Gl.glCallList(I + 1)
Next

If GrabSelection = True Then
GrabSelection = False
Dim h As Integer = Gl.glRenderMode(Gl.GL_RENDER)
If h > 0 Then
ParseBuffer(h)
End If
Gl.glPopMatrix()
Else
'present draw
Gl.glFlush()
Gdi.SwapBuffers(hDC)
End If

End Sub


... but i still get the same problem... i'm going to give up.

GClements
12-19-2015, 06:33 AM
I tried to change my code like that:


Gl.glMatrixMode(Gl.GL_PROJECTION)
Gl.glLoadIdentity()
Glu.gluPerspective(10.0#, P.Width / P.Height, 0.1#, 10000.0#)

If GrabSelection = True Then
Gl.glGetIntegerv(Gl.GL_VIEWPORT, V)
Glu.gluPickMatrix(GrabX, GrabY, 5, 5, V)


It needs to be part of the projection matrix, before any perspective or orthographic projection is applied.

I.e. the gluPickMatrix() needs to be immediately after the glLoadIdentity() and before the gluPerspective().

bindes1974@libero.it
12-19-2015, 10:20 AM
It needs to be part of the projection matrix, before any perspective or orthographic projection is applied.

I.e. the gluPickMatrix() needs to be immediately after the glLoadIdentity() and before the gluPerspective().

Yes!! Finally it works! Thanks again for the quick reply and... sorry, I did not pay enough attention to your first post.:):):)

Right code:


Gl.glMatrixMode(Gl.GL_PROJECTION)

If GrabSelection = True Then
Gl.glGetIntegerv(Gl.GL_VIEWPORT, V)
Gl.glLoadIdentity()
Glu.gluPickMatrix(GrabX, GrabY, 5, 5, V)
Glu.gluPerspective(10.0#, P.Width / P.Height, 0.1#, 10000.0#)
Gl.glRenderMode(Gl.GL_SELECT)
Else
Gl.glLoadIdentity()
Glu.gluPerspective(10.0#, P.Width / P.Height, 0.1#, 10000.0#)
End If