Hello everyone,
I'm in a bit of a bind for a while now concerning object picking. Here's the situation:
Our company has recently been implementing OpenGL into our Delphi 2010 programs and our current assignment is to display voyages of several trains in a 3D-esque environment.
Everything works and is data-aware (connected to a database); our client/customer now wants the ability to open the voyage-information when you click on a train.
I went looking for a tutorial and came across this: http://www.sulaco.co.za/opengl_project_GL_picking.htm
Studied the code, dissected the code, applied the code to our own project but it doesn't function.
One thing I've noticed is this:
The 'tutorial' uses a Viewport whereas I use a Context; the latter is because we have to use several Delphi Tools like a date-time selection bar on our Form.
Here is an image of the ContextView:
And here is the code I'm using for the Object Picking:
Pushing names into the list:Code :function TGL_Form.RetrieveObjectID(x, y: integer): integer; var objectsFound: integer; viewportCoords: array [0..3] of integer; selectBuffer: array[0..31] of cardinal; lowestDepth: cardinal; selectedObject: cardinal; i: integer; begin objectsFound := 0; ZeroMemory(@viewportCoords, sizeof(viewportCoords)); ZeroMemory(@selectBuffer, sizeof(selectBuffer)); glSelectBuffer(32, @selectBuffer); viewportCoords[0] := 0; viewportCoords[1] := 0; viewportCoords[2] := GL_Form.ClientWidth; viewportCoords[3] := GL_Form.ClientHeight; glMatrixMode(GL_PROJECTION); glPushMatrix(); glRenderMode(GL_SELECT); glLoadIdentity(); gluPickMatrix(x, viewportCoords[3]-y-Integer(not g_Fullscreen)*(GetSystemMetrics(SM_CYCAPTION)+ GetSystemMetrics(SM_CYSIZEFRAME) shl 1), 15, 15, @viewportCoords); gluPerspective(45.0, viewportCoords[2]/viewportCoords[3], 0.5, 150.0); glMatrixMode(GL_MODELVIEW); objectsFound := glRenderMode(GL_RENDER); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); if (objectsFound > 0) then begin lowestDepth := selectBuffer[1]; selectedObject := selectBuffer[3]; for i := 1 to objectsFound - 1 do begin if (selectBuffer[(i * 4) + 1] < lowestDepth) then begin lowestDepth := selectBuffer[(i * 4) + 1]; selectedObject := selectBuffer[(i * 4) + 3]; end; end; result := selectedObject; exit; end; result := 0; end;
Code ://Draw the trains glInitNames(); glPushName(0); for T1 := 0 to Length(trackNames)-1 do for T2 := 0 to Length(trackTrack)-1 do if(trackNames[T1] = trackTrack[T2]) then begin glLoadName(T2); Y := -((T1 * trackWidth) + (T1 * trackSpace))+0.5; glCube(trackFrom[T2]*(trackLength/58), Y, 0, ((trackTo[T2]-trackFrom[T2])*(trackLength/58)), //Length trackWidth, //Height 0.09, //Depth trackColorR[T2], trackColorG[T2], trackColorB[T2] ); glPrint(trackVoyage[T2], trackFrom[T2]*(trackLength/58)+1, Y+2, 0.1, textColorR[T2], textColorG[T2], textColorB[T2], false ); glEnd(); end;
Using breakpoints I've adjusted the code accordingly and tested to see where it goes awry:
This part ALWAYS returns 0Code :glRenderMode(GL_SELECT); glLoadIdentity(); gluPickMatrix(x, viewportCoords[3]-y-Integer(not g_Fullscreen)*(GetSystemMetrics(SM_CYCAPTION)+ GetSystemMetrics(SM_CYSIZEFRAME) shl 1), 15, 15, @viewportCoords); gluPerspective(45.0, viewportCoords[2]/viewportCoords[3], 0.5, 150.0); glMatrixMode(GL_MODELVIEW); objectsFound := glRenderMode(GL_RENDER);
The 'x' and 'y' have the correct mouse positions stored,
data in 'viewportCoords' is correct; [0, 0, 1024, 768],
'g_FullScreen' is always 'false',
I have no idea what 'GetSystemMetrics(SM_CYCAPTION)', 'GetSystemMetrics(SM_CYSIZEFRAME)' or '(GetSystemMetrics(SM_CYCAPTION)+ GetSystemMetrics(SM_CYSIZEFRAME) shl 1)' have for values because they're untracable for some reason; neither a breakpoint nor storing the data (Integers) shows any result, though I have a few more methods that might work, will update on this..
##UPDATE##
'GetSystemMetrics(SM_CYCAPTION)' = 23
'GetSystemMetrics(SM_CYSIZEFRAME)' = 8
'(GetSystemMetrics(SM_CYCAPTION)+ GetSystemMetrics(SM_CYSIZEFRAME) shl 1)' = 39
'viewportCoords[3]-y-Integer(not g_Fullscreen)*(GetSystemMetrics(SM_CYCAPTION)+ GetSystemMetrics(SM_CYSIZEFRAME) shl 1)' = returns a value based on the mouseposition (changes)
I hope someone can help me with fixing this, because I'm at a loss at the moment.
Thanks in advance and kind regards.