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

Aktuelle Zeit: Di Jul 15, 2025 16:33

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 11 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Mo Jul 25, 2011 19:08 
Offline
DGL Member

Registriert: Mo Jul 25, 2011 18:15
Beiträge: 25
Wohnort: Nürnberg
Programmiersprache: C#
Hallo Leute,

ich hoff ihr könnt mir beim Verstehen von etwas Grundsätzlichem helfen.
Aktuell implementiere ich fuer OpenGl die Selection Mögleichkeit.

Zuerst wie üblich ueber den selection-buffer (bzw. Render Mode).

Problem hierbei:
1.) Die Fläche zum Klicken die das Object "erwischt" ist immer kleiner oder verschoben als das gezeichnete Object
2.) sobald ich rotiere wird nichts mehr selektiert

Da dies nicht funktioniert hatte...
Nächster Schritt: Selection via der Farbmethode (jedes Object in eindeutiger Farbe zeichnen und Farbe auslesen)

Problem:
1.) Die Fläche welche die nachgezeichnete Farbe erwischt ist immer kleiner als das Object, daneben wird
die Orginalfarbe (gemischt mit dem Licht) zurückgegeben?
(z.B. Rechteck mit Seitenfläche 2 und Farbe Blau, bei Selection in rot gezeichnet,
-> Bei Selection wird der Bereich im Bereich 0-> 1 als rot und darüberhinaus als blau zurückgegeben )

Da ich bei Selection in die Projektionsmatrix zeichne und sonst in die ModelView Matrix denke ich das hierbei der unterschied liegt???
Könnt ihr mir paar Ideen liefern wie ich diesem Fehler nachkomme bzw. ueberhaupt Themen denen ich nachgehen kann?. Nachfolgend der Code in kürze:

//Paint Methode
private void openGlControl1_Paint(object sender, PaintEventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glPointSize(3);
this.DrawScene(true); <- Zeichnet meine Objekte
}

//Selection Methode (bekommt die x & y Koordinaten übergeben)
private int ObjectSelection(int xs, int ys)
{
byte [] treffer = {0,0,0};

Gl.glMatrixMode(Gl.GL_PROJECTION); //In den Projektionsmodus
Gl.glLoadIdentity(); //Und dieselbige wieder zurückzusetzen
Gl.glPushMatrix(); //Um unsere Matrix zu sichern

Gl.glDisable(Gl.GL_COLOR_MATERIAL);
Gl.glDisable(Gl.GL_LIGHT0);
Gl.glDisable(Gl.GL_LIGHTING);
Gl.glDisable(Gl.GL_BLEND);
Gl.glDisable(Gl.GL_DEPTH_TEST);

Glu.gluPerspective(45.0f, (double) glWidth / (double)glHeight, 1f, 1000f);

this.DrawScene(false); //Die Szene zeichnen

Gl.glReadPixels(xs, glHeight - ys, 1, 1, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, @treffer);
Gl.glPopMatrix(); //und unsere alte Matrix wiederherzustellen

return treffer[0];
}


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jul 25, 2011 20:23 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
chrisfn hat geschrieben:
Da ich bei Selection in die Projektionsmatrix zeichne und sonst in die ModelView Matrix denke ich das hierbei der unterschied liegt???


Wie meinst du das? Man zeichnet nicht "in" eine Matrix, sondern die Matrix wird benutzt um deine Vertices zu Transformieren. Normalerweise benutzt man immer beide (Projection und Modelview) Matrizen.

Im Endeffekt ändern sich die Matrizen beim ColorPicking nicht, sondern es sind die gleichen wie beim "normalen" Rendern. Der einzige Unterschied ist eben, dass man die Texturen/Beleuchtung/Effekte ausschaltet und jedes Objekt mit einer eindeutigen Farbe zeichnet. Im Wiki ist auch ein Tutorial das erklärt wie man ColorPicking realisiert (mit und ohne Shadern). Vielleicht findest du dort was nützliches.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jul 25, 2011 20:46 
Offline
DGL Member

Registriert: Mo Jul 25, 2011 18:15
Beiträge: 25
Wohnort: Nürnberg
Programmiersprache: C#
Hallo Markus,

ich setze beim selektieren "Gl.glMatrixMode(Gl.GL_PROJECTION)" anstatt "Gl.glMatrixMode(Gl.GL_MODELVIEW"); jedoch entnehme ich deiner Antwort
das dies das Problem nicht hervorruft...

Ich hab schon einige Tutorials abgespikt (bin noch Anfänger) jedoch immer mit dem gleichen Ergebnis...
Die Methode mit selection Buffer habe ich den Tutorials "Object_Selection_A" und "Object_Selection_B" der DGLWiki entnommen....


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mo Jul 25, 2011 21:08 
Offline
DGL Member

Registriert: Mo Dez 20, 2010 19:31
Beiträge: 11
Zitat:
Gl.glMatrixMode(Gl.GL_PROJECTION); //In den Projektionsmodus
Gl.glLoadIdentity(); //Und dieselbige wieder zurückzusetzen
Gl.glPushMatrix(); //Um unsere Matrix zu sichern

Wie wäre es mit Gl.glLoadIdentity(); und Gl.glPushMatrix(); zu vertauschen?
Wenn nicht muesstest du sie ja nicht Pushen.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jul 26, 2011 11:12 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Du solltest beim ColorPicking genau die gleichen Matrizen nehmen wie beim normalen Zeichnen. Du willst ja eben, dass deine Objekte genauso gezeichnet werden wie normal, nur halt mit eindeutigen Farben.

Du solltest also (was die Matrizen angeht) genau die gleichen Einstellungen vornehmen wie beim normalen Rendern.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jul 26, 2011 15:14 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jul 23, 2009 04:33
Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Gl.glDisable(Gl.GL_DEPTH_TEST);
Den Tiefentest sollte man normalerweise nicht ausschalten für Selektion. Nur wenn man einen Grund dafür hat. Ansonsten kann das zu sehr merkwürdigen Ergebnissen führen; entweder lässt sich das Objekt auch dann noch selektieren, wenn es eigentlich unsichtbar hinter einem anderen liegt*; oder es lässt sich nicht selektieren, weil es von anderen Objekten verdeckt wird, obwohl sich diese eigentlich hinter dem zu selektierenden Objekt befindet.

Texture, Light usw. sollte man ausschalten, das hast du richtig gemacht. Aber Depth_Test halt nur wenn's wirklich Sinn macht.

*) wenn das gewünscht ist, ist es meistens Sinnvoller die verdeckenden Objekte gar nicht erst zu Zeichnen. Wenn man in seinem Spiel z.B. Gras und Bäume hat, und Häuser selektieren will, kann man beim ColorSelect einfach das Gras und die Bäume beim Zeichnen weglassen, dann stören sie nicht, und schneller geht es auch noch.

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jul 26, 2011 17:35 
Offline
DGL Member

Registriert: Mo Jul 25, 2011 18:15
Beiträge: 25
Wohnort: Nürnberg
Programmiersprache: C#
Danke für die Ideen...

Sobald ich "Gl.glDisable(Gl.GL_DEPTH_TEST);" auskommentiere bekomme ich leider
gar keine richtigen Werte zurück, d.h. auch nicht an den Stellen die vorher funktioniert haben :(

Auch das tauschen von LoadIdentity und PushMatrix hat erst mal keine erkennbaren Änderungen gebracht..


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Di Jul 26, 2011 18:08 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
Zeig doch mal ein bisschen mehr Code... so kann man immer nur raten.


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 27, 2011 13:15 
Offline
DGL Member

Registriert: Mo Jul 25, 2011 18:15
Beiträge: 25
Wohnort: Nürnberg
Programmiersprache: C#
Hab den Code so reduziert das immer nur ein Rechteck gezeichnet werden soll!

//1. Die Initialisierung
public Form1()
{
InitializeComponent();
this.openGlControl1.InitializeContexts(); // init OpenGl Object

glWidth = this.openGlControl1.Size.Width; // Set OpenGL Object width
glHeight = this.openGlControl1.Size.Height; // Set OpenGL Object height

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, mat_specular);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, mat_shininess);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_AMBIENT, mat_ambient);
Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, mat_diffuse);

//Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, light_specular);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, light_ambient);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, light_diffuse);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, light_position);

Gl.glEnable(Gl.GL_COLOR_MATERIAL);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glEnable(Gl.GL_DEPTH_TEST);

Gl.glClearDepth(1.0);
Gl.glClearColor(0, 0, 0, 0);
Gl.glDepthMask(Gl.GL_TRUE);

Gl.glViewport(0, 0, glWidth, glHeight);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glLoadIdentity();
Glu.gluPerspective(45.0f, (double)glWidth / (double)glHeight, 1f, 1000.0f);
Gl.glEnable(Gl.GL_CULL_FACE);
Gl.glCullFace(Gl.GL_BACK);
}


//2. Die Paint Methode um den "Bildschirm zu zeichnen"

private void openGlControl1_Paint(object sender, PaintEventArgs e)
{
Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();
Gl.glPointSize(3);
this.DrawScene(true);
}

//3. Die Draw Methode um die Vertexes zu zeichnen
//hier stark vereinfacht

private void DrawScene(Boolean drawMode)
{
Gl.glTranslatef(shiftX, shiftY, zoom);
Gl.glRotated(rotAngle, 0, 1, 0);

Gl.glPushMatrix();
if (drawMode==true)
{
Gl.glColor3ub(10, 10, 200);
}
else
{
Gl.glColor3ub(100, 0, 0);
}
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3f(0, 0, 0);
Gl.glVertex3f(0.5f, 0, 0);
Gl.glVertex3f(0.5f, 0.5f, 0);
Gl.glVertex3f(0, 0.5f, 0);
Gl.glEnd();
Gl.glPopMatrix();
}

// 4. Die Selection Methode
private int ObjectSelection(int xs, int ys)
{
byte [] treffer = {0,0,0};

Gl.glPushMatrix();

Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glLoadIdentity();

Gl.glDisable(Gl.GL_COLOR_MATERIAL);
Gl.glDisable(Gl.GL_LIGHT0);
Gl.glDisable(Gl.GL_LIGHTING);
Gl.glDisable(Gl.GL_BLEND);
//Gl.glDisable(Gl.GL_DEPTH_TEST);

Glu.gluPerspective(45.0f, (double) glWidth / (double)glHeight, 1f, 1000f);

this.DrawScene(false); //Die Szene zeichnen
Gl.glReadPixels(xs, glHeight - ys, 1, 1, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, @treffer);

Gl.glPopMatrix();
return treffer[0];
}

//Alle weiteren Methoden lass ich mal aus, da die nur für die Tastenfunktionen, Schattenberechnung ect. sind
//Die DrawScene Methode hab ich mal dermaßen vereinfacht um dem Problem auf den Grund zu gehen


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 27, 2011 14:26 
Offline
DGL Member
Benutzeravatar

Registriert: Fr Mär 30, 2007 18:35
Beiträge: 331
So in etwa:

Code:
  1.  
  2. // 4. Die Selection Methode
  3. private int ObjectSelection(int xs, int ys)
  4. {
  5. byte [] treffer = {0,0,0};
  6.  
  7. // backbuffer und colorbuffer clearen, damit alles neu gezeichnet wird
  8. Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);
  9.  
  10. Gl.glPushMatrix();
  11.  
  12. // Hier musst du die *gleiche* Modelview-Matrix wie beim normalen Rendern setzen
  13. Gl.glMatrixMode(Gl.GL_MODELVIEW);
  14. Gl.glLoadIdentity();
  15.  
  16. // glPointSize auch setzen
  17. Gl.glPointSize(3);
  18.  
  19. Gl.glDisable(Gl.GL_COLOR_MATERIAL);
  20. Gl.glDisable(Gl.GL_LIGHT0);
  21. Gl.glDisable(Gl.GL_LIGHTING);
  22. Gl.glDisable(Gl.GL_BLEND);
  23. //Gl.glDisable(Gl.GL_DEPTH_TEST);
  24.  
  25. // Eventuell noch Texturen ausmachen
  26. glDisable(GL_TEXTURE_2D);
  27.  
  28. // Keine perspektive setzen! Das hast du bei der initialisierung schon gemacht, deswegen hier nicht nötig.
  29. // Außerdem setzt du sie dann zweimal, einmal in der PROJECTION und einmal in der MODELVIEW Matrix,
  30. // das führt aber nicht zum gewünschten Ergebnis.
  31. // Glu.gluPerspective(45.0f, (double) glWidth / (double)glHeight, 1f, 1000f);
  32.  
  33. this.DrawScene(false); //Die Szene zeichnen
  34. Gl.glReadPixels(xs, glHeight - ys, 1, 1, Gl.GL_RGB, Gl.GL_UNSIGNED_BYTE, @treffer);
  35.  
  36. Gl.glPopMatrix();
  37. return treffer[0];
  38. }


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: Mi Jul 27, 2011 14:40 
Offline
DGL Member

Registriert: Mo Jul 25, 2011 18:15
Beiträge: 25
Wohnort: Nürnberg
Programmiersprache: C#
Hallo Markus,

vielen Dank nochmal für deine Mühe.
Hab so einiges ausprobiert aber wohl das mit der Perspektive weglassen nicht :(
Genau das war es!!!

Also vielen Dank nochmal an alle die sich im Forum soviel Mühe machen anderen zu helfen!!!!!


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 9 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:  
cron
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 14 Queries | GZIP : On ]