Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 09, 2025 11:54

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
BeitragVerfasst: So Nov 07, 2010 15:30 
Offline
DGL Member
Benutzeravatar

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 :D ). 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)
Code:
unit uDLFight;

interface

uses
  dglOpenGL, Windows, SysUtils, Classes, Graphics, Forms, Controls, textures, uLog;

const
  NearClipping = 0;
  FarClipping  = 128 + 1; // +1 um auch die Ebene 128 anzuzeigen
  SizeX = 1024;
  SizeY = 768;
const
  Sel_PlayerFlag1 = 1;
  Sel_PlayerFlag2 = 2;

type
  TIntializeData = record
    TableWidth, TableHeight : Integer; // Höhe und Breite in Feldanzahl

    FigursPerPlayer : Integer;
    DLLPathPlayer1, DLLPathPlayer2 : string;
  end;

  TWinEvent = procedure(Sender: TObject; WinnerID : Integer) of Object;

  TDLMatch = class(TObject)
  private
    DC                                : HDC;  //Handle auf Zeichenfläche
    RC                                : HGLRC;//Rendering Context
    OGLDisplay : TWinControl;

    function IntializeOGL(Parent : TWinControl):boolean;
    procedure SetupGL;
  public
    Framerate : Integer;

    OnEndMatch : TWinEvent;
    procedure DisplayMouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure IdleHandler(Sender: TObject; var Done: Boolean);
    procedure Render;
    function Selection(xs,ys : Integer) : integer;
    constructor Create(pDisplay : TWinControl; Data : TIntializeData);
    destructor  Destroy(); override;
  end;

implementation

{ TDLMatch }

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

  gluPickMatrix(xs, viewport[3]-ys, 1.0, 1.0, viewport);
  gluPerspective(60.0, Viewport[2]/Viewport[3], NearClipping, FarClipping);

  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);

  glMatrixMode(GL_PROJECTION);
    glLoadIdentity;
    SetupGL;

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity;

  glInitNames;
  glPushName(0);

  //----------------------------------------------------------------------------
  glLoadName(1);
  glBegin(GL_QUADS);
    glVertex3f(050,50,-128); // unten links
    glVertex3f(100,50,-128); // unten rechts
    glVertex3f(100,100,-128); // oben rechts
    glVertex3f(50,100,-128); // oben links
  glEnd;

  glRotatef(90,0,0,1);

  glLoadName(2);
  glBegin(GL_QUADS);
    glVertex3f(50,50,-128); // unten links
    glVertex3f(100,50,-128); // unten rechts
    glVertex3f(100,100,-128); // oben rechts
    glVertex3f(50,100,-128); // oben links
  glEnd;
  //----------------------------------------------------------------------------

  SwapBuffers(DC);
end;

procedure TDLMatch.SetupGL;
begin
  glOrtho(-(SizeX/2), SizeX/2, -(SizeY/2), SizeY/2, NearClipping, FarClipping);         // Aktiviert 2D Perspektive
  glViewport(0,0,OGLDisplay.ClientWidth,OGLDisplay.ClientHeight);
  glEnable(GL_DEPTH_TEST);                                        // Aktiviert Tiefentest
  glDepthFunc(GL_LESS);                                             // Depth Buffer Setup
end;

end.


So jetzt fangen meine Spekulationen an :mrgreen:

Ich vermute dass es irgendwie mit dem zu tun hat was ich in SetupGL einstelle, spezieller mit
Code:
  glOrtho(-(SizeX/2), SizeX/2, -(SizeY/2), SizeY/2, NearClipping, FarClipping);

Also damit dass bei mir die Perspektive wegfällt und alles "2D" gerendert wird

Ich hoffe einer von euch weisen OpenGL-Meistern :wink: 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.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 15:37 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Zitat:
Code:
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

  gluPickMatrix(xs, viewport[3]-ys, 1.0, 1.0, viewport);
  gluPerspective(60.0, Viewport[2]/Viewport[3], NearClipping, FarClipping);

Bei der Selektion brauchst du natürlich die gleiche Projektionsmatrix wie beim rendern. Also eine orthogonale Projektion. Ersetze das gluPerspective durch glOrtho...

P.S. Willkommen im Forum :)

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 15:59 
Offline
DGL Member
Benutzeravatar

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

  gluPickMatrix(xs, viewport[3]-ys, 1.0, 1.0, viewport);
  glOrtho(-(SizeX/2), SizeX/2, -(SizeY/2), SizeY/2, NearClipping, FarClipping);

  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 :D

_________________
This is Schäuble. Copy Schäuble into your signature to help him on his way to Überwachungsstaat.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 16:02 
Offline
DGL Member

Registriert: Do Jan 07, 2010 21:58
Beiträge: 240
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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 16:05 
Offline
DGL Member
Benutzeravatar

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.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 16:14 
Offline
DGL Member

Registriert: Mo Aug 31, 2009 13:19
Beiträge: 151
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 :D AUch von mir also noch ein "Willkommen im Forum" ;)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Nov 07, 2010 22:14 
Offline
Guitar Hero
Benutzeravatar

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


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Nov 08, 2010 08:56 
Offline
DGL Member

Registriert: Mo Aug 31, 2009 13:19
Beiträge: 151
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.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.013s | 17 Queries | GZIP : On ]