Die Selektionsfunktion von OpenGL ist fehleranfällig und hinzu kommtm, daß sie auf nVidia-Karten mit aktuellen Treibern ziemliche Performanceschwankungen verursacht. Hier wird eine alternative Methode vorgestellt. Sie wurde aus einem funktionierendem Projekt entnommen. Sie wurde aber angepasst, um Allgemeingültigkeit wieder herzustellen.

procedure Render;
begin
   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
   Hauptklasse.Render(FALSE);
   SDL_GL_SwapBuffers;
end;

procedure THauptklasse.Render(Picken:Boolean);
begin
   for objekt:=0 To Pred(objekte.count) do
   begin
   if Picken then
   begin
     glDisable(GL_TEXTURE_2D);
     glColor4b(objekt, 0, 0, 0); //Die Farbe wird in diesem Fall auf Rot geschreiben. Damit kann man 256 Objekte unterscheiden. Hat man mehr Objekte, kann man auch alle Farben verwenden.
     //glbegin(GL_QUADS);
     // Alles rendern.
     //glend;
   end else
   begin
     glEnable(GL_TEXTURE_2D);
     //glbegin(GL_QUADS);
     // Alles rendern.
     //glend;
     end;
   end;
end;


Nun wird implementiert, daß beim Mausklick ein extra Rendervorgang angestossen wird, welcher die zu unterscheidenden Objekte lediglich mit verschiedenen eindeutigen Farben rendert. Dieser Rendervorgang wird nach dem Auslesen des Pickergebnisses sofort wieder überschrieben und bleibt damit unsichtbar.
Dazu brauchen wir folgende Methode, welche beim Mausklick diesen Rendervorgang anstoesst und und das Pickergebnis liefert.

function GetSelectBufferHit(mx,my:Integer) : Integer;
var DataBuffer : array [0..3]of Byte;
begin
   Hauptklasse.Render(TRUE); // Im Pickmodus rendern //
   glReadPixels(mx, game.SCREEN_HEIGHT-my, 1, 1, GL_RGB, GL_BYTE, @DataBuffer);
   Result := DataBuffer[0];
end;


Die Methode GetSelectBufferHit wird dann im Klickevent gerufen. In SDL-Projekten sieht das etwa so aus:

procedure glHandleEvents;
var event : TSDL_Event;
hit:Integer;
begin;
   // Verarbeiten der Events
   while ( SDL_PollEvent( @event ) = 1 ) do
   begin
     case event.type_ of
  
     // Maustaste wurde gedrückt
     SDL_MOUSEBUTTONDOWN:
     begin
       Hit := GetSelectBufferHit(Event.button.x,Event.button.y);
       //Die Nummer auf "Hit" ist unsere ID, welche wir beim Rendern auf die Objektfarbe gelegt hatten.
  
   end;
...
end;