Registriert: So Nov 07, 2010 14:08 Beiträge: 11
Programmiersprache: Delphi
Hallo,
ich bin gerade dabei ein kleines 2d-Projekt mit OpenGL zu realisieren mithilfe des 2D-Tutorials (http://wiki.delphigl.com/index.php/Tutorial_2D). Das funktioniert so weit auch klasse (Ein Lob an den Ersteller des Tuts ). Jetzt wollte ich jedoch einen Knopf einführen auf den man klicken kann, deshalb zog ich das Objektselektionstutorial (http://wiki.delphigl.com/index.php/Tutorial_Selection) zu Rate. Leider funktioniert das ganze nicht so wie es soll.
Um das ganze zu verdeutlichen hab ich mal meinen Code solange reduziert bis nur noch das wesentliche da ist, er zeichnet nurnoch 2 Quads und spuckt bei jedem Klick die Nummer aus auf die geklickt wurde (Quad1 = 1 Quad2 = 2 ^^ ). Das Problem ist jetzt jedoch dass er immer 1 auspuckt. Hier der (reduzierte) Code: (Die kompilierte exe ist auch im Anhang)
function TDLMatch.Selection(xs,ys : Integer) : integer; var Puffer : array[0..256] of GLUInt; Viewport : TGLVectori4; Treffer,i : Integer; Z_Wert : GLUInt; Getroffen : GLUInt; begin glGetIntegerv(GL_VIEWPORT, @viewport); //Die Sicht speichern glSelectBuffer(256, @Puffer); //Den Puffer zuordnen
glMatrixMode(GL_PROJECTION); //In den Projektionsmodus glRenderMode(GL_SELECT); //In den Selectionsmodus schalten glPushMatrix; //Um unsere Matrix zu sichern glLoadIdentity; //Und dieselbige wieder zurückzusetzen
Render; //Die Szene zeichnen glMatrixMode(GL_PROJECTION); //Wieder in den Projektionsmodus glPopMatrix; //und unsere alte Matrix wiederherzustellen
treffer := glRenderMode(GL_RENDER); //Anzahl der Treffer auslesen
Getroffen := High(GLUInt); //Höchsten möglichen Wert annehmen Z_Wert := High(GLUInt); //Höchsten Z - Wert for i := 0 to Treffer-1 do if Puffer[(i*4)+1] < Z_Wert then begin getroffen := Puffer[(i*4)+3]; Z_Wert := Puffer[(i*4)+1]; end;
if getroffen=High(GLUInt) then Result := -1 else Result := getroffen; end;
constructor TDLMatch.Create(pDisplay : TWinControl; Data : TIntializeData); begin inherited create;
OGLDisplay := pDisplay; if not IntializeOGL(pDisplay) then raise Exception.Create('OpenGL was not intialized correctly');
SetupGL; end;
destructor TDLMatch.destroy(); begin DeactivateRenderingContext; DestroyRenderingContext(RC); ReleaseDC(OGLDisplay.Handle, DC);
inherited destroy; end;
procedure TDLMatch.DisplayMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var iSelection : Integer; begin iSelection := Selection(X,Y); if (iSelection=Sel_PlayerFlag1)OR(iSelection=Sel_PlayerFlag2) then begin dl_Log('SELECTION'); end; dl_Log(iSelection); end;
procedure TDLMatch.IdleHandler(Sender: TObject; var Done: Boolean); begin Render; sleep(1); // zur Prozessorschonung, ggf deaktivieren Done:= false; end;
function TDLMatch.IntializeOGL(Parent : TWinControl):boolean; begin DC:= GetDC(Parent.Handle); RC:= CreateRenderingContext( DC, [opDoubleBuffered], 32, 24, 0,0,0, 0); ActivateRenderingContext(DC, RC); end;
procedure TDLMatch.Render; begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Also damit dass bei mir die Perspektive wegfällt und alles "2D" gerendert wird
Ich hoffe einer von euch weisen OpenGL-Meistern kann mir helfen - bzw sagen wo das Problem liegt
Schon mal im vorraus danken ... Mike
[Edit] Ich weiss nicht was ich falsch mache aber scheinbar kann ich die Datei hier irgendwie nicht hochladen .. falls sie aber jemand sehen will hab ich sie hier nich mal auf RS : http://rapidshare.com/files/429411370/DLF.zip [/Edit]
_________________ This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat.
glMatrixMode(GL_PROJECTION); //In den Projektionsmodus glRenderMode(GL_SELECT); //In den Selectionsmodus schalten glPushMatrix; //Um unsere Matrix zu sichern glLoadIdentity; //Und dieselbige wieder zurückzusetzen
Bei der Selektion brauchst du natürlich die gleiche Projektionsmatrix wie beim rendern. Also eine orthogonale Projektion. Ersetze das gluPerspective durch glOrtho...
Registriert: So Nov 07, 2010 14:08 Beiträge: 11
Programmiersprache: Delphi
Ok, das habe ich jetzt gemacht, jetzt sieht die Selection-Methode so aus:
Code:
function TDLMatch.Selection(xs,ys : Integer) : integer; var Puffer : array[0..256] of GLUInt; Viewport : TGLVectori4; Treffer,i : Integer; Z_Wert : GLUInt; Getroffen : GLUInt; begin glGetIntegerv(GL_VIEWPORT, @viewport); //Die Sicht speichern glSelectBuffer(256, @Puffer); //Den Puffer zuordnen
glMatrixMode(GL_PROJECTION); //In den Projektionsmodus glRenderMode(GL_SELECT); //In den Selectionsmodus schalten glPushMatrix; //Um unsere Matrix zu sichern glLoadIdentity; //Und dieselbige wieder zurückzusetzen
Render; //Die Szene zeichnen glMatrixMode(GL_PROJECTION); //Wieder in den Projektionsmodus glPopMatrix; //und unsere alte Matrix wiederherzustellen
treffer := glRenderMode(GL_RENDER); //Anzahl der Treffer auslesen
Getroffen := High(GLUInt); //Höchsten möglichen Wert annehmen Z_Wert := High(GLUInt); //Höchsten Z - Wert for i := 0 to Treffer-1 do if Puffer[(i*4)+1] < Z_Wert then begin getroffen := Puffer[(i*4)+3]; Z_Wert := Puffer[(i*4)+1]; end;
if getroffen=High(GLUInt) then Result := -1 else Result := getroffen; end;
Leider hat sich an dem Effekt bzw dem Problem nicht geändert
Zitat:
P.S. Willkommen im Forum
Danke
_________________ This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat.
wobei du im 2D modus nicht umbedingt eine selektion brauchst, ein schlichtes abfragen der koordinaten der maus und vergleichen mit denen des objects würde reichen
Registriert: So Nov 07, 2010 14:08 Beiträge: 11
Programmiersprache: Delphi
Dropye hat geschrieben:
wobei du im 2D modus nicht umbedingt eine selektion brauchst, ein schlichtes abfragen der koordinaten der maus und vergleichen mit denen des objects würde reichen
Stimmt eigentlich ... ja ich glaube so mach ich das (ist auch einfacher).
Danke Dropje
MfG Mike
_________________ This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat.
Ich weiß aus eigener Erfahrung, dass man hier im Forum oft gesagt bekommt "Machs einfach anders..." und das nicht gerne hören will - meistens hat das Forum dabei allerdings recht. Wenn du in 2D feststellen willst, worauf geklickt wurde, dann ist ein schlichter Vergleich über die Mauskoordinaten wirklich das Einfachere.
Soweit zu dem was Dropye schon gesagt hat XD...Dazu kommt noch, dass du dir ausgerechnet eine Selektionsmethode ausgesucht hast, die OpenGL in den Softwaremodus katapultiert. Wenn man Selektion via OpenGL umsetzen will, dann meistens am besten via Colorselection. Ich weiß, da steht am Tutorial dran, man bräuchte Shader und Shader sind böses Teufelswerk - Der Shader wird allerdings im Grunde nur benutzt, um zu verhindern, dass Pixel gerendert werden, die wegen ihrer Texturierung einen bestimmten Alphawert unterschreiten. Wenn du ein wenig aufpasst kannst du ihn also auch einfach weglassen
P.S.: Jetzt hab ich gerade in der Vorschau gesehen, dass du schon geantwortet hattest - aber ich will mein +1 noch AUch von mir also noch ein "Willkommen im Forum"
Registriert: Do Sep 25, 2003 15:56 Beiträge: 7810 Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Steht das mit den Shadern wirklich da? Ich denke es wäre an der Zeit einen hinweis im Selektions Tutorial einzubauen und auf ColorPicking zu verweisen. Es gibt ja auch eine Shaderfreie anleitung das zu implementieren.
_________________ Blog: kevin-fleischer.de und fbaingermany.com
Was? Das Shader böses Teufelswerk sind? Nein, das steht natürlich nicht da - aber erfahrungsgemäß ist dass die Meinung, die man nach der Lektüre der ersten 3 Tutorials von Shadern hat. Deswegen lässt man da ja anfangs lieber die Finger von. Das die Implementierung aus dem Tut nur mit Shadern funktioniert steht da allerdings tatsächlich, ja.
Mitglieder in diesem Forum: 0 Mitglieder und 4 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.