Results 1 to 7 of 7

Thread: GL Picking

  1. #1

    GL Picking

    Hi all,

    Im having a little trouble with GL Picking.. it works fine when there are 2 or more objects to select, how ever if i click in a space where there is no objects it always select the last object created.. heres a screenshot:



    I can select the left and the right faces without a problem, but if for example i click in the very bottom right cornour, the left face is always selected.

    below is the code im using in the OnClick event of my mouse class:

    Code:
    procedure GLOnClick(const X,Y: Integer; const Button: TXGUIMouseButton);
    var
      selectBuff : Array Of Cardinal;
      vp: TVector4i;
      hits,SelectedName: Cardinal;
      Obj: TXObject;
    begin
      SetLength(selectBuff, _XObjects.Count);
    
      glGetIntegerv(GL_VIEWPORT, @vp);  
      glSelectBuffer(_XObjects.Count, @selectBuff);
    
      glMatrixMode(GL_PROJECTION);
      glPushMatrix;
        glRenderMode(GL_SELECT);
        _XEngine.Selection := True;
    
        glInitNames;
        glPushName(0);
        glLoadIdentity;
    
        gluPickMatrix(X, Y, 1, 1, vp);
        gluPerspective(45.0, vp[2]/vp[3], 0.1, 100.0);  
        glMatrixMode(GL_MODELVIEW);
    
        _XEngine.DoRender;
    
        hits := glRenderMode(GL_RENDER);
    
        Obj := Nil;
        If (hits > 0) Then
        Begin
          SelectedName := selectBuff[3];
          Obj := _XO_Find(SelectedName);
        End;
        _XEngine.Selected := Obj;
    
        glMatrixMode(GL_PROJECTION);
      glPopMatrix;
      _XEngine.Selection := False;
      glMatrixMode(GL_MODELVIEW);
    end;
    and in the objects rendering code i have:
    Code:
      If Not Visible Then Exit;
      If _XEngine.Selection Then glLoadName(fID);
      glPushMatrix;
        PreRender(Options);
        DoRender(Options);
        PostRender(Options);
      glPopMatrix;
    .. fID is a unique ID.

    I have double checked it with several tutorials and examples but i cant seem to find anything i have missed :?

    Can anyone see if i have missed something, or is this something with SDL/OpenGL?
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  2. #2

    GL Picking

    After rendering the objects that you want to pick load another name to the name stack with glLoadName(), like glLoadName(MaxObjectID + 1) to prevent picking the last object.
    If you develop an idiot proof system, the nature develops better idiots.

  3. #3

    GL Picking

    Thanks for the quick reply

    I have added the following just after the render function:
    Code:
        glLoadName&#40;_XObjects.Count+99&#41;;
    yet it still selects the last face in the list :?

    The selectbuff[3] has '2' assigned to it which is the id of the second face, and not of the blank one above..
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  4. #4

    GL Picking

    Here's how I process the hits in my engine:

    [pascal]

    var
    SelectBuffer : array[0..512] of TGLUInt;
    Viewport : TGLVectori4;
    Hits,i : Integer;
    HitZValue : TGLUInt;
    Hit : TGLUInt;

    ...
    Set the picking matrix etc.
    Draw stuff
    ...

    glFlush();
    Hits := glRenderMode(GL_RENDER);

    // Now we look which hit has the lowest Z-Value i.e. was in front
    Hit := High(TGLUInt);
    HitZValue := High(TGLUInt);
    for i := 0 to Hits-1 do
    if SelectBuffer[(i*4)+1] < HitZValue then
    begin
    Hit := SelectBuffer[(i*4)+3];
    HitZValue := SelectBuffer[(i*4)+1];
    end;
    [/pascal]

    In this case Hit will be -1 if no object was at the given x/y coordinates or it will be set to the front-most object id found.
    If you develop an idiot proof system, the nature develops better idiots.

  5. #5

    GL Picking

    Thanks for the code

    It didnt work at first, after a little fiddling i have managed to get it to work.. for some reason the first element in the buffer was always set at 4294965246 and resulted in only the first item being selected. however i have managed to get around this by doing:
    Code:
    If &#40;Hits > 0&#41; And &#40;&#40;selectBuff&#91;1&#93; <> 0&#41; Or &#40;selectBuff&#91;2&#93; <0> lZ Then
        Begin
          lZ &#58;= z;
          hObj &#58;= selectBuff&#91;&#40;i*4&#41;+3&#93;;
        End;
      End;
      ....
    End;
    This seems to work fine at the moment, but only time will tell and as i test the editor and the rest of the engine i will see if it works

    Thanks for your help
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  6. #6

    GL Picking

    dont you should initialize "selectBuff" before using, somting like fillchar(selectbuffer[0],length(selectbuffer),0); ?

  7. #7

    GL Picking

    yeah you are right, im not sure why i used fillchar, but now i have it in a for loop
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •