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: GL Picking - Delphi OpenGL Projects
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:
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;
Pushing names into the list:
//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:
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);
This part ALWAYS returns 0
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.