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

Aktuelle Zeit: Mi Jul 09, 2025 22:14

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



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Selektion in C++
BeitragVerfasst: Do Jun 01, 2006 16:24 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 01, 2006 15:51
Beiträge: 4
Guten Tag..
Erst einmal ganz herzliche Gratulation zu den Tutorials, wir müssen fürs Studium ein Universum simulieren, doch die (franzöischen) Unterlagen des Professors sind leider schrecklich. Dank eurer Hilfe habe ich nun zumindest ansatzweise den Überblick. :) Nur die krasse Abneigung gegenüber Matrizen kann ich nicht ganz verstehen... :wink:

Nun aber meine Frage: Ich habe die beiden Tutorials zur Selektion einzelner Objekte gelesen, und den Code sogut ich weiss den c++ standards angepasst. Es kompiliert wunderbar, nur werden keine Objekte ausgewählt:
Code:
  1.  
  2. int GUI::locate_body(int x,int y) const {
  3. //  inspired by wiki.delphigl.com/index.php/Tutorial_Selection //Ehre, wem Ehre gebührt... <!-- s:) --><img src=\"{SMILIES_PATH}/icon_smile.gif\" alt=\":)\" title=\"Smile\" /><!-- s:) -->
  4.     GLint viewport[4];
  5.     glGetIntegerv(GL_VIEWPORT, viewport);
  6.     GLuint buffer[256];
  7.     glSelectBuffer(256,buffer);               //Den Puffer zuordnen
  8.     glRenderMode(GL_SELECT);           //In den Selectionsmodus schalten
  9.     glInitNames();
  10.     glPushName(0);
  11.     glMatrixMode(GL_PROJECTION);     //In den Projektionsmodus
  12.     glPushMatrix();                               //Um unsere Matrix zu sichern
  13.         glLoadIdentity();                             //Und dieselbige wieder zurückzusetzen
  14.         gluPickMatrix(x, viewport[3]-y, 1.0, 1.0, viewport);
  15.         gluPerspective(45.0, viewport[2], 1.0, 1000);
  16.         glutPostRedisplay();                                     //Die Szene zeichnen
  17.         glMatrixMode(GL_PROJECTION);                //Wieder in den Projektionsmodus
  18.     glPopMatrix();                                //und unsere alte Matrix wiederherzustellen
  19.     int hits(glRenderMode(GL_RENDER));         //Anzahl der Treffer auslesen
  20.     cout << "#hits: " <<hits << endl;
  21.     for (int i(0); i<hits; ++i) cout << i<< endl;
  22.     if (hits!=0) {
  23.         GLuint touched(buffer[3]);
  24.         GLuint z_coordinate(buffer[1]);
  25.         for (int i(1); i<hits; ++i) {
  26.             if (buffer[(i*4)+1] < z_coordinate) {
  27.                 touched = buffer[(i*4)+3];
  28.                 z_coordinate = buffer[(i*4)+1];
  29.             }
  30.         }
  31.         return touched-1;
  32.     }
  33.     else return -3;
  34. }
  35.  

Das mit dem High(GLuint) funktioniert nicht, deshalb lese ich direkt den ersten Wert aus (wenn's denn einen hat).
GUI ist meine Klasse, und die DisplayFunc ist die folgende:
Code:
  1.  
  2. void display() {
  3.         glMatrixMode(GL_MODELVIEW);
  4.         if (!interface->trace()) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  5.         glLoadIdentity();
  6.         Vector3D p,a,v;
  7.         my_camera.getParameters(p,a,v);
  8.         gluLookAt(  p.getX(), p.getY(), p.getZ(),
  9.                     a.getX(), a.getY(), a.getZ(),
  10.                     v.getX(), v.getY(), v.getZ());
  11.         // draw axes (to be implemented ..maybe)
  12.         my_universe->draw();
  13.         glutSwapBuffers();
  14. }  
  15.  

Und das zugehörige my_universe->draw() lautet:
Code:
  1.  
  2. void Universe::draw() const {
  3.     glInitNames();
  4.     glPushName(0);
  5.     for (int i(0); i<serie_bodies.size(); ++i) { // draw each object from objectList
  6.               serie_bodies[i]->draw();
  7.     }
  8. }
  9.  

Hier bezeichnet serie_bodies ein Vektor mit verschiedenen Himmelskörper, je mit einer Funktion draw() bestückt:
Code:
  1.  
  2. void Body::draw() const {
  3.     glPushMatrix(); // save current settings
  4.     color.colorGlut(); // chose the color for the sphere //funktioniert <!-- s:) --><img src=\"{SMILIES_PATH}/icon_smile.gif\" alt=\":)\" title=\"Smile\" /><!-- s:) -->
  5.     glTranslated(   position.getX(),        // move the zero position
  6.                 position.getY(),        // to the center
  7.                 position.getZ());       // of the body
  8.     glLoadName(index+1);//add glut identifier
  9.     glutSolidSphere(radius, N_SLICES, N_STACKS);
  10.     //add name
  11.     glRasterPos3d(dist, dist, dist);
  12.     const char* s(name.c_str());
  13.     while (*s) {
  14.         glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *s);
  15.         s++;
  16.     }
  17.     glPopMatrix(); //return to previous settings
  18. }
  19.  


Nun wie schon gesagt, die Darstellung klappt immer noch wunderbar, auch die Simulation und alles. Aber der eingebaute cout<< "#hits" gibt mir ständig an, dass kein Körper gefunden wurde. Was ist wohl das Problem??

.. und, nebenbei, ist es richtig, dass ich glInitNames() mehrmals aufrufe? Braucht es da nicht noch irgend einen glFertigNames? ;)
//edit: cpp tags hinzugefügt.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Selektion in C++
BeitragVerfasst: Do Jun 01, 2006 16:58 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Willkommen auf DGL :D

Code:
  1.     glMatrixMode(GL_PROJECTION);     //In den Projektionsmodus
  2.     glRenderMode(GL_SELECT);           //In den Selectionsmodus schalten
  3.     glPushMatrix();                               //Um unsere Matrix zu sichern
  4.         glLoadIdentity();                             //Und dieselbige wieder zurückzusetzen
  5.         gluPickMatrix(x, viewport[3]-y, 1.0, 1.0, viewport);
  6.         gluPerspective(45.0, viewport[2], 1.0, 1000);
  7.         glutPostRedisplay();                                     //Die Szene zeichnen
  8.         glMatrixMode(GL_PROJECTION);                //Wieder in den Projektionsmodus
  9.     glPopMatrix();                                //und unsere alte Matrix wiederherzustellen


Ich habe hier im Code mal die Reihenfolge von glMatrixMode und glRendermode umgedreht damit es dem Tut(1) entspricht. Dann habe ich das Initnames an der Stelle entfernt, da ich davon ausgehe, dass es vor Body.draw gesetzt wird. Es muss übrigens nur einmal nach dem Wechsel in den Rendermodus GL_SELECT aufgerufen werden, damit der Stack initialisiert wird. glFertigNames gibt es nicht, dies geschieht automatisch beim (Zurück)Wechseln des Rendermodus.
Denoch ist mehrfach aufrufen solange nicht schädlich wie du Sachen gepusht hast.

Die Sache mit dem High(GLUInt) dient einfach nur dazu, dass man einen Wert hat, von dem man sicher sein kann, dass es kein Objekt ist.
Laut Shaijan entspricht es übrigens:
Code:
  1.  i >> 16
  2. //oder als Makro:
  3. HIGHWORD

Aber das ergänzt er lieber selber :)

Andere Fehler in dem Code finde ich gerade nicht.
Übrigens sind Matrizen ganz nette Sachen solange man sie nicht invertieren muss :(
Aber die Tuts richten sich auch an Leute die Matrizen nicht kennen müssen. Man macht sie halt recht spät in der Schule und nicht jeder studiert Mathe (Was auch gut ist :) )


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 17:06 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Nov 13, 2004 11:00
Beiträge: 229
Wohnort: Steinhude
high(GLuInt) liefert schlicht und ergreifend den größten Wert zurück, den ein GLuInt annehmen kann, also $FFFFFFFF oder auch 4294967295. Das ist etwas anderes als der höhere Anteil eines DWords.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 17:09 
Offline
DGL Member
Benutzeravatar

Registriert: Di Sep 06, 2005 18:34
Beiträge: 362
Wohnort: Hamburg
Hi ...

das mit dem High(...) hatte ich im IRC falsch verstanden, dachte das wär zum auslesen der obersten 16 Bit eines 32 Bit Integers (HIWORD-Makro in C++, daher *g*), hatte den Thread halt noch nicht gefunden ;)

Wenn man in C++ einer Variable ihren höchstmöglichen Wert geben will, muss man die "limits.h" einbinden, sollte standardmäßig vorhanden sein. Dort stehen die als Konstanten drin.
Bei nem GLuint (unsigned int) wäre das also UINT_MAX als Konstante oder (wie sollte es auch anders sein) 0xFFFFFFFF als Hexwert.
D.h. du müsstest dort, wo im Delphicode High(GLuint) steht einfach das oben genannte einsetzen ...

Gruß
Shai

_________________
Der Mensch hat neben dem Trieb der Fortpflanzung und dem zu essen und zu trinken zwei Leidenschaften: Krach zu machen und nicht zuzuhören. (Kurt Tucholsky)
Schwabbeldiwapp, hier kommt die Grütze. (Der Quästor)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 17:47 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 01, 2006 15:51
Beiträge: 4
Dass ich anstelle von glCallList ein glutSolidSphere verwendet habe, sollte kein Problem sein?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 21:23 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Nein, weil egal was du Zeichnest mit dem zuletzt vergeben "Namen" versehen wird. Egal was kommt.

PS: Willkommen auf DelphiGL.com ;)

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jun 06, 2006 21:29 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 01, 2006 15:51
Beiträge: 4
(einer) der Fehler lag übrigens darin, dass glPostRedisplay() das Fenster lediglich markiert, damit es in der nächsten Glut Schlaufe wieder gezeichnet wird. Was in meinem Fall bedeutet, dass die Namen erst hinzugefügt werden, wenn der RenderMode schon wieder auf GLRender gesetzt ist.

Tja, ... jetzt kann ich zumindest die Elemente in der Mitte anklicken.. wenn sie denn nicht zu weit hinten sind. - Ich glaube nicht, dass es an den Perspektiveneinstellungen liegt, die sind an beiden Orten gleich eingestellt.. aber kann mir vielleicht jemand erklären, warum es in dem Codeabschnitt überhaupt nötig ist, die Perspektive zu setzen?
... ich habe sie eben schon einmal mit dem gleichen Befehl gesetzt, und glMatrixMode war da schon GL_PROJECTION. Muss es neu gesetzt werden, weil man sich jetzt im GL_SELECT modus befindet?!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Perspektivenproblem
BeitragVerfasst: Fr Jun 09, 2006 23:19 
Offline
DGL Member
Benutzeravatar

Registriert: Do Jun 01, 2006 15:51
Beiträge: 4
Code:
  1.  
  2. #include <iostream>
  3. #include "GLUT/glut.h"
  4. using namespace std;
  5.  
  6. int window;
  7.  
  8. /* _______________________________________________________________  */
  9. /* _____________________ GLOBAL FUNCTIONS ______________________    */
  10. void reshape(int width, int height) {
  11.     if (height <= 0) height = 1;
  12.     double ratio(width);
  13.     ratio /= height;
  14.     glMatrixMode(GL_PROJECTION);
  15.     glLoadIdentity();
  16.     glViewport(0, 0, width, height);
  17.     gluPerspective(45.0, ratio, 1.0, 1000.0);
  18.     glMatrixMode(GL_MODELVIEW);
  19.     glLoadIdentity();
  20. }
  21.  
  22. void idle(void) {
  23.   glutPostRedisplay();
  24.   glutIdleFunc(0);
  25. }
  26.  
  27. void keyboard(unsigned char key, int mouse_x, int mouse_y) {
  28.         switch (key) {
  29.         case 27 :
  30.         case 'q':
  31.         case 'Q':  
  32.             glutDestroyWindow(window);
  33.             exit(0);
  34.             break;
  35.         }
  36.         glutPostRedisplay();
  37. }
  38.  
  39. int locate_body(int x, int y);
  40.  
  41. void mouse(int button, int state, int x, int y) {
  42.         switch (button) {
  43.             case GLUT_RIGHT_BUTTON:
  44.                 if (state==GLUT_DOWN) {
  45.                     int index(locate_body(x,y));                       
  46.                     if (index >= 0) {
  47.                     }
  48.                     cout << "clicked on Body nr "<< index << endl;
  49.                 }
  50.                 break;
  51.         }
  52. }
  53.  
  54. void display() {
  55.     glMatrixMode(GL_MODELVIEW);
  56.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  57.     glLoadIdentity();
  58.     gluLookAt(  0, 0, -100,
  59.                 0, 30, 0,                                     /////// ********siehe kommentar unten********
  60.                 5, 0, 0);
  61.     glInitNames();
  62.     glPushName(0);
  63.     glPushMatrix(); // save current settings
  64.     glLoadName(1);//add glut identifier
  65.     glColor4d(1.0,1.0,1.0,1.0);
  66.     glutSolidSphere(4, 30, 30);
  67.     glPopMatrix(); //return to previous settings
  68.     glutSwapBuffers();
  69.  
  70. int locate_body(int x,int y) {
  71. //  inspired by wiki.delphigl.com/index.php/Tutorial_Selection
  72.     GLint viewport[4];
  73.     cout << "locate_body" << endl;
  74.     glGetIntegerv(GL_VIEWPORT, viewport);
  75.     GLuint buffer[256];
  76.     glSelectBuffer(256,buffer);               //Den Puffer zuordnen
  77.     glMatrixMode(GL_PROJECTION);     //In den Projektionsmodus
  78.     glRenderMode(GL_SELECT);           //In den Selectionsmodus schalten
  79.     glPushMatrix();                               //Um unsere Matrix zu sichern
  80.         glLoadIdentity();                             //Und dieselbige wieder zurückzusetzen
  81.         gluPickMatrix(x, y, 5.0, 5.0, viewport);
  82.         gluPerspective(45.0, viewport[2]/viewport[3], 1.0, 1000);
  83.         display();                                     //Die Szene zeichnen
  84.         glMatrixMode(GL_PROJECTION);                //Wieder in den Projektionsmodus
  85.     glPopMatrix();                                //und unsere alte Matrix wiederherzustellen
  86.     int hits(glRenderMode(GL_RENDER));         //Anzahl der Treffer auslesen
  87.     cout << "#hits: " <<hits << endl;
  88.     if (hits!=0) {
  89.         GLuint touched(buffer[3]);
  90.         GLuint z_coordinate(buffer[1]);
  91.         for (int i(1); i<hits; ++i) {
  92.             if (buffer[(i*4)+1] < z_coordinate) {
  93.                 touched = buffer[(i*4)+3];
  94.                 z_coordinate = buffer[(i*4)+1];
  95.             }
  96.         }
  97.         return touched-1;
  98.     }
  99.     else return -3;
  100. }
  101.  
  102. int main(int argc, char *argv[]) {
  103.     glutInit(&argc, argv);
  104.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  105.     glutInitWindowSize(800, 600);
  106.     window = glutCreateWindow("Press Q to exit");
  107.     glutDisplayFunc(display);
  108.     glutIdleFunc(idle);
  109.     glutKeyboardFunc(keyboard);
  110.     glutMouseFunc(mouse);
  111.     glutReshapeFunc(reshape);
  112.     // enables a correct display of the hidden parts
  113.     glEnable(GL_DEPTH_TEST);
  114.     glDepthFunc(GL_LESS);
  115.     glEnable(GL_BLEND);
  116.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  117.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  118.     glutMainLoop();
  119.     return 0;  
  120. }
  121.  


Wenn ich dieses Beispielprogramm laufen lasse, habe ich genau das gleiche Problem wie das schon genannte... um genau zu sein.. ist die ****** Zeile auf 0,0,0 gesetzt (die Kugel im Zentrum) funktioniert das anwählen wunderbar. Mit den Werten 0,30,0 ist die Klick-Region verschoben. Trotzdem habe ich nie eine andere Projektion gewählt. Hat irgend jemand eine Ahnung, warum?


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 5 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.010s | 14 Queries | GZIP : On ]