Zubaja

04-01-2014, 07:36 AM

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:

http://i1273.photobucket.com/albums/y413/Steven_Nolles/GleisGleisGleis_zpsf385d686.png

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.

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:

http://i1273.photobucket.com/albums/y413/Steven_Nolles/GleisGleisGleis_zpsf385d686.png

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.