Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

07.06.2009, 17:57

picking

hiho,

ich versuche bei mir picking von objekten vom typen sphere zu realisieren. ich verteile sie zufällig im raum und möchte nun, wenn ich mit der maus auf eine kugel klicke, wissen, um welche kugel es sich handelt. leider funktioniert es nicht. wenn ich drauf klicke, wird irgendein bereich gezeichnet :/ leider nur nicht die kugel. kommt hinzu, dass der rückgabewert von GL11.glRenderMode(GL11.GL_RENDER); 0 ist.

anbei mal meine selection-methode

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  private void selection(){
     
    // The selection buffer
    IntBuffer selBuffer = BufferUtils.createIntBuffer(256);
    IntBuffer vpBuffer = BufferUtils.createIntBuffer(64);
    
    // The number of "hits" (objects within the pick area).
    int hits=0;

    // Get the viewport info
    GL11.glGetInteger(GL11.GL_VIEWPORT, vpBuffer);
            
    // Set the buffer that OpenGL uses for selection to our buffer
    GL11.glSelectBuffer(selBuffer);
          
    // Change to selection mode
    GL11.glRenderMode(GL11.GL_SELECT);
          
    // Initialize the name stack (used for identifying which object was selected)
    GL11.glInitNames();
    GL11.glPushName(0);
          
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glPushMatrix();
    GL11.glLoadIdentity();
          
    //  create 5x5 pixel picking region near cursor location 
    System.out.println("x: "+mouse_x + " y:" + (vpBuffer.get(3) - mouse_y));
    GLU.gluPickMatrix(mouse_x, (vpBuffer.get(3) - mouse_y), 1.0f, 1.0f, vpBuffer);
    GL11.glOrtho(0.0, 8.0, 0.0, 8.0, -0.5, 2.5);
    
  //  loadEnvironment(GL11.GL_SELECT);
   
    GL11.glMatrixMode(GL11.GL_PROJECTION);
    GL11.glPopMatrix();
    GL11.glFlush();

    hits = GL11.glRenderMode(GL11.GL_RENDER);
    System.out.println("Number: " + hits);
    
  }


im konkreten bin ich noch nicht soweit, irgendwelche sachen auszuwerten. solange hits 0 ist, scheint es mir sowieso nichts zu bringen.

habt ihr eine idee, was hier falsch läuft

3dcoder

Frischling

Beiträge: 40

Wohnort: Krefeld

  • Private Nachricht senden

2

07.06.2009, 19:43

Hi!

Du verwendest eine andere Projektion für das Picking als für das Rendern selbst - d.h. OpenGL bekommt im SELECT-Mode andere Ergebnisse wenn du renderst (was du aber nicht tust, da loadEnvironment auskommentiert ist?!).

Meine Vorschläge:
- entferne mal den glOrtho-Call und das glLoadIdentity 5 Zeilen drüber und lass die GL_PROJECTION Matrix so wie sie ist.
- lass loadEnvironment laufen (falls das die Methode ist die deine Szene zeichnet) - ansonsten füge dort eben diese mal ein.

Dann sollte es funktionieren.

Im besten Fall erhälst du natürlich beim glRenderMode Aufruf eine "1" zurück und im SelectBuffer die ID "0" - denn du setzt ja auch nur einen einzigen Namen mit glPushName: 0 eben.

Viel Erfolg!
Grüße
Stefan

3

07.06.2009, 20:17

hm.. scheint so auch nicht zu helfen. ogl ist auch nicht grad meine stärke. da aber nach ändern der selection-methode das ergebnis das selbe war, könnte es vielleicht auch an der implementierung der spheres liegen?

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  private int createDL(){
    //Displayliste erstellen
    int sphereDL;
    // parameter = anzahl displaylisten
    sphereDL = GL11.glGenLists(1);
    GL11.glNewList(sphereDL, GL11.GL_COMPILE);
      //zeichne spheres
      nodes.draw(0.2f, 16, 16);
      
    GL11.glEndList();
    return (sphereDL);
  }

  // method draws all sphere objects on screen (
  private void loadEnvironment(int mode){
    //GL11.glInitNames();
    //GL11.glRenderMode(GL11.GL_SELECT);
    // Draw A Sphere With A Radius Of 1 And 32 Longitude And 32 Latitude Segments
    for(int i = 0; i < numSpheres; i++)
    {
    if (mode == GL11.GL_SELECT) GL11.glLoadName(i);
    GL11.glPushMatrix();
    //objekt auf namestack
    GL11.glPushName(i);
            xPos = randomFloat[i];
            yPos = randomFloat[i+1];
            zPos = randomFloat[i+2];
            GL11.glVertex3f(xPos,yPos,zPos);
            GL11.glTranslatef(xPos, yPos, zPos);
            //displayliste ausfuehren
            GL11.glCallList(DLsphere);
            GL11.glTranslatef(-xPos, -yPos, -zPos);
        GL11.glPopName();
        GL11.glPopMatrix();

         
    }
    GL11.glRenderMode(GL11.GL_RENDER);
    }

3dcoder

Frischling

Beiträge: 40

Wohnort: Krefeld

  • Private Nachricht senden

4

07.06.2009, 21:51

Hi!

Ich gehe mal davon aus, dass der Aufruf

Quellcode

1
nodes.draw(0.2f, 16, 16); 

funktioniert und die Kugel wie erwartet zeichnet.

Der Fehler scheint mir in der letzten Zeile zu liegen:
Warum rufst du am Ende der Methode loadEnvironment

Quellcode

1
GL11.glRenderMode(GL11.GL_RENDER);
auf?
Dieser Aufruf muss raus, denn du fragst ja den Rückgabewert später
nochmal ab und durch diesen Aufruf vernichtest du ihn ja vorab schon -
OpenGL liefert dir nur dann den richtigen Rückgabewert bei dieser
Methode wenn ein _Wechsel_ des RenderModes stattfand - was so aber
nicht mehr der Fall ist.

Dann fallen mir noch an deinem Code folgende Dinge auf (darin liegt aber der Fehler nicht):

- glVertex3f darf nur zwischen glBegin und glEnd auftauchen. Du brauchst es hier aber auch nicht. Kann also raus.
- glTranslatef mit den negativen Koordinaten kann raus wenn du nachher eh die Matrix mit glPopMatrix zurückstellst
- glPushName und glPopName können auch raus wenn du mit glLoadName den aktuellen Namen schon setzt.

Bin gespannt obs nun funktioniert!

Grüße
Stefan

Werbeanzeige