Autor |
Beitrag |
P-A-L
Beiträge: 30
|
Verfasst: Mo 21.01.13 21:05
Hallo zusammen,
seit über einem Jahr liegt mein Projekt auf Eis, weil ich die Selektion von Objekten nicht hinbekomme. Jetzt wende ich mich demütig an die wahren Gurus - Euch!
Ich verwende im Prinzip die Code-Basis aus dem DGL Wiki Tutorial zu Selektion, nur eben erweitert um ein paar Objekte.
Was ich machen möchte: Eine Karte aus 5x5 Hex-Feldern zeichnen (funktioniert) und bei Klick auf eines der Felder den jeweiligen Namen (glLoadName) ausgeben (funktioniert nicht!).
Wenn man jetzt klickt, wird immer derselbe Name ausgegeben, egal ob man ein Objekt getroffen haben sollte oder nicht.
Ich verzweifle da echt dran... Hilfe!!!
EDIT: Ich habe zu Testzwecken die Namensvergabe geändert - also Bitte keine Hinweise á la "Du hast die Namensvergabe auskommentiert" oder so was
Meine Render-Routine:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure TF_Game.Render; var i:integer; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45.0, ClientWidth/ClientHeight, NearClipping, FarClipping);
glMatrixMode(GL_MODELVIEW); glLoadIdentity; glInitNames; glPushName(0);
theCamera.Apply; glLoadName(15); gamemap.draw; glLoadName(1);
glEnd;
SwapBuffers(DC); L_StatusBar.Caption:=text_coords + ' - ' + text_fps + ' - ' + text_info + ' - ' + text_error; end; |
Das wird bei Mausklick aufgerufen (soll selektieren):
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:
| function TF_Game.getSelectBufferHit():integer; var SelectBuffer : array[0..512] of TGLUInt; Viewport : TGLArrayi4; Hits,i : Integer; HitZValue : TGLUInt; Hit : TGLUInt; begin glGetIntegerv(GL_VIEWPORT, @viewport); glSelectBuffer(512, @SelectBuffer); glRenderMode(GL_SELECT); glMatrixMode(GL_PROJECTION); glPushMatrix; glLoadIdentity; gluPickMatrix(mx, viewport[3]-my, 1.0, 1.0, dglOpenGL.TVector4i(viewport)); gluPerspective(45.0, ClientWidth/ClientHeight, 0.1, 1000); Render; glMatrixMode(GL_PROJECTION); glPopMatrix; Hits := glRenderMode(GL_RENDER); 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; Result := Hit; end; |
Und das sind die HexTile und HexMap Objekte:
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: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90:
| type TCoord = record Col : integer; Row : integer; end;
type THexTile = class private _ID : integer; public constructor create(col,row:integer); function getID():integer; function getxy():TCoord; procedure draw(); end;
type TMap = class _tiles : array of array of THexTile; _sizeRows : cardinal; _sizeCols : cardinal; procedure draw(); procedure load(); end; constructor THexTile.Create(col,row: integer); begin inherited Create(); _ID := row*1000+col; end;
function THexTile.getID() : integer; begin result:=_ID; end;
function THexTile.getxy():TCoord; begin result.Col := _ID mod 1000; result.Row := _ID div 1000; end;
procedure THexTile.draw; begin glLoadName(88); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glBegin(GL_POLYGON); glTexCoord2f(0.75,0); glVertex3f(0.5,sqrt(0.75),0); glTexCoord2f(0.25,0); glVertex3f(-0.5,sqrt(0.75),0); glTexCoord2f(0,0.5); glVertex3f(-1,0,0); glTexCoord2f(0.25,1); glVertex3f(-0.5,-sqrt(0.75),0); glTexCoord2f(0.75,1); glVertex3f(0.5,-sqrt(0.75),0); glTexCoord2f(1,0.5); glVertex3f(1,0,0); glEnd; end;
procedure TMap.load; var r,c: integer; begin setlength(_tiles, _mapsize_x, _mapsize_y); for r:=0 to _mapsize_y-1 do for c:=0 to _mapsize_x-1 do Begin _tiles[c,r]:=THexTile.Create(c,r); end; end;
procedure TMap.draw; var r,c : integer; x,y : double; begin glMatrixMode(GL_MODELVIEW); glloadidentity;
For r:= 0 To _mapsize_y-1 do For c:=0 to _mapsize_x-1 do Begin theCamera.Apply; x:=1+(c*1.5); y:=(-1)*((2*r+((c+1) mod 2)+1)*sqrt(0.75)); gltranslatef(x,y,0); _tiles[c,r].draw; End; end; |
Moderiert von Martok: Code- durch Delphi-Tags ersetzt
Einloggen, um Attachments anzusehen!
|
|
Jens01
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 3
|
Verfasst: Mo 21.01.13 21:58
Wenn ich richtig gesehen habe, dann setzt Du mit "glLoadName" den Namen/Nummer auf 15 und renderst alle Objekte. Du mußt aber mit "glLoadName" den Namen/Nummer setzen und das Objekt rendern, das diesen Namen zurückgeben soll, dann wieder neuen Namen setzen und nächstes Objekt rendern usw.
|
|
P-A-L
Beiträge: 30
|
Verfasst: Di 22.01.13 16:56
Jens01 hat folgendes geschrieben : | Wenn ich richtig gesehen habe, dann setzt Du mit "glLoadName" den Namen/Nummer auf 15 und renderst alle Objekte. Du mußt aber mit "glLoadName" den Namen/Nummer setzen und das Objekt rendern, das diesen Namen zurückgeben soll, dann wieder neuen Namen setzen und nächstes Objekt rendern usw. |
Hallo Jens,
danke für die Antwort. Wie gesagt, ich hatte mit dem Naming rumgespielt um den Fehler zu finden, diese Zeile war Teil der Tests. Ich werde versuchen, heute abend mal einen "sauberen" Quelltext hochzuladen.
In der Routine "THexTile.Draw" wird das einzelne HexTile mit seiner ID als Name belegt (hier im Quelltext auskommentiert), funktioniert aber trotzdem nicht - es wird immer 15 als Selektion zurückgegeben. Wenn ich den glLoadName(15) entferne, wird halt alles als "0" ausgegeben.
Der Fehler muss also entweder in der GetSelectBufferHit() oder in THexTile.Draw liegen... Oder ich rufe die Routinen in der falschen Reihenfolge auf...
Ich bin bald so weit, ein Preisgeld für das Finden des Bugs auszuloben :p
|
|
Jens01
Hält's aus hier
Beiträge: 9
Erhaltene Danke: 3
|
Verfasst: Di 22.01.13 18:02
Guck Dir mal meine CamerAH www.delphigl.com/for....php?f=13&t=9811 an.
Die ist Deiner genutzten Kamera ähnlich und hat auch schon Teile für diese Selektion. Eine weitere Möglichkeit der Selektion (und wohl auch die besser Option) ist dies Colorpicking.
Eigentlich ganz einfach.
|
|
Bergmann89
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Di 22.01.13 20:25
Hey,
das glInitNames und glPushNames(0) muss definitiv rein, das initialisiert die ganzen Sachen. Außerdem initialisierst du in deinem Render-Code die ProjektionsMatrix neu, dann is die PickMatrix wieder weg. Also Zeilen 6-8 aus dem RenderCode raus. Wenn das nich hilft, mach das gluPickMatrix mal größer (100x100) und lass den RenderMode auf GL_RENDER, dann kannst du dir angucken, ob da überhaupt das richtige gerendert wird.
€: Ich seh grad das du InitNames und PushNames(0) im RenderCode hast... Dann kann es eig. nur noch an der Projektion liegen...
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
P-A-L
Beiträge: 30
|
Verfasst: Di 22.01.13 21:26
Bergmann89 hat folgendes geschrieben : | Hey,
das glInitNames und glPushNames(0) muss definitiv rein, das initialisiert die ganzen Sachen. Außerdem initialisierst du in deinem Render-Code die ProjektionsMatrix neu, dann is die PickMatrix wieder weg. Also Zeilen 6-8 aus dem RenderCode raus. Wenn das nich hilft, mach das gluPickMatrix mal größer (100x100) und lass den RenderMode auf GL_RENDER, dann kannst du dir angucken, ob da überhaupt das richtige gerendert wird.
€: Ich seh grad das du InitNames und PushNames(0) im RenderCode hast... Dann kann es eig. nur noch an der Projektion liegen...
MfG Bergmann. |
Bergmann, TAUSEND DANK, das war's!!! Ich kann Dir gar nicht sagen wie dankbar ich Dir dafür bin!!!
*Tief Verbeug*
Jens01 hat folgendes geschrieben : | Guck Dir mal meine CamerAH www.delphigl.com/for....php?f=13&t=9811 an.
Die ist Deiner genutzten Kamera ähnlich und hat auch schon Teile für diese Selektion. Eine weitere Möglichkeit der Selektion (und wohl auch die besser Option) ist dies Colorpicking.
Eigentlich ganz einfach. |
Danke Jens, sieht sehr gut aus. Bin gerade dabei das in meinen Code einzubauen und werd Dir dann Rückmeldung geben ob's passt.
|
|
|