Probleme mit dem Licht in OpenGL

  • Probleme mit dem Licht in OpenGL

    Hallo alle.
    Ich arbeite gerade an einer Gravitationssimulation mit n Körpern im Raum. In meinem Beispielprojekt gibt es derzeit 3 Körper. Ohne Einfluss auf die Berechnungen kann ich in meinem Fenster einstellen, ob ich eine normale Darstellung der Kugeln wünsche (dann nutze ich gluSphere) oder eine Darstellung als "Metaballs" (dann nutze ich Vertex-, Normal- und Colorarrays). Dazu habe ich den "Marching Cubes Algorithmus" implementiert. Klappt auch alles soweit super, ich habe allerdings ein Problem mit den Lichtverhältnissen. Und zwar verstehe ich trotz langem Suchen und Überlegen nicht, warum die beiden Darstellungen unterschiedliche Lichtverhältnisse zeigen, obwohl die Generierung des Lichts beide Male identisch ist. Zunächst dachte ich an Fehler in der Berechnung meiner Normalen während der Darstellung im Metaball-Mode, aber ich habe sie mir anzeigen lassen und die Berechnung stimmt.

    Ich habe ein allgemeines Lichtmodell angeschaltet:

    Quellcode

    1. GLfloat ambient[] = {0.5f, 0.5f, 0.5f, 0.5f};
    2. glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);



    Zusätzlich ein Licht 0 aktiviert:

    Quellcode

    1. glEnable( GL_LIGHT0 );
    2. glLightfv( GL_LIGHT0, GL_AMBIENT, (*[light ambient]).rgba );
    3. glLightfv( GL_LIGHT0, GL_SPECULAR, (*[light specular]).rgba );
    4. glLightfv( GL_LIGHT0, GL_POSITION, pos);



    Arbeite mit Color Material und setze die Farbe dann mit glColor4v:

    Quellcode

    1. glEnable(GL_COLOR_MATERIAL);
    2. glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);



    Zunächst wird der Beobachter gesetzt:

    Quellcode

    1. glMatrixMode(GL_MODELVIEW);
    2. glLoadIdentity();
    3. glClearColor(0.0, 0.0, 0.0, 0.0);
    4. glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    5. gluLookAt([[[observer spacePoint] position] x], [[[observer spacePoint] position] y],
    6. [[[observer spacePoint] position] z],
    7. [[observer lookAt] x],
    8. [[observer lookAt] y],
    9. [[observer lookAt] z],
    10. [[[observer spacePoint] up] x],
    11. [[[observer spacePoint] up] y],
    12. [[[observer spacePoint] up] z]);
    Alles anzeigen



    So stelle ich grundsätzlich die Metaballs dar:

    Quellcode

    1. glEnableClientState(GL_COLOR_ARRAY);
    2. glEnableClientState(GL_VERTEX_ARRAY);
    3. glEnableClientState(GL_NORMAL_ARRAY);
    4. glPushMatrix();
    5. glVertexPointer(3, GL_DOUBLE, sizeof(vertex), &([[[observer owner] mc] vertices][0].pos[0]));
    6. glNormalPointer(GL_DOUBLE, sizeof(vertex), &([[[observer owner] mc] vertices][0].norm[0]));
    7. glColorPointer(3, GL_FLOAT, sizeof(vertex), &([[[observer owner] mc] vertices][0].color[0]));
    8. glDrawArrays(GL_TRIANGLES, 0, [[[observer owner] mc] verticesCount]);
    9. glPopMatrix();
    10. glDisableClientState(GL_VERTEX_ARRAY);
    11. glDisableClientState(GL_NORMAL_ARRAY);
    12. glDisableClientState(GL_COLOR_ARRAY);
    Alles anzeigen



    Und so alternativ die gluSpheres:

    Quellcode

    1. glPushMatrix();
    2. sphere = gluNewQuadric();glColor4fv( (*[object diffuse]).rgba );
    3. glTranslated([p x], [p y], [p z]);
    4. gluQuadricDrawStyle(sphere, GL_FILL);
    5. gluSphere(sphere, [object radius], [object slices], [object stacks]);
    6. gluDeleteQuadric(sphere);
    7. glPopMatrix();



    Ich habe mich jetzt auf die aus meiner Sicht relevanten Befehle beschränkt zu Gunsten der Übersichtlichkeit. Es st ein altes Projekt und ich weiß, dass manches vielleicht "depraced" ist. Daher würden mich natürlich vornehmlich Ideen zu den unterschiedlichen Lichtverhältnissen interessieren, weniger allgemeine Verbesserungsvorschläge, außer wenn es damit zusammenhängt. Auch wenn manchem Profi wahrscheinlich die Haare zu Berge stehen wegen des alten Codes.
    Ich hänge nochmal zwei Bilder an, um zu zeigen, wo mein Problem mit dem Licht liegt. Erklären kann ich es mir nicht.

    Über alle Ideen bin ich sehr dankbar.

    Liebe Grüße.
  • Mh, schwierig zu sagen, ich tippe trotzdem mal auf die Normalen. Hast Du mal glEnable(GL_NORMALIZE); probiert?

    Mach mal zum testen aus

    Quellcode

    1. glNormalPointer(GL_DOUBLE, sizeof(vertex), &([[[observer owner] mc] vertices][0].norm[0]));


    Quellcode

    1. glNormalPointer(GL_FLOAT, sizeof(vertex), &([[[observer owner] mc] vertices][0].norm[0]));
  • Was noch auffällt ist, das das Licht (der blaue Kreis? ) auf dem 2. Bild anders aussieht. Dann scheint das Problem aber woanders zu liegen.
    State falsch gesetzt ?
    Mach mal ein glgetError rein
  • Also auf dem ersten Bild werden alle Körper mit gluSphere erstellt, auf dem zweiten alle mit dem Marching Cubes Algorithmus. Habe auch das Licht 0 mal weiter von der Szene entfernt, nicht, dass beim Marching Cubes Algorithmus ggf. die Kugeln sehr dezent größer sind und plötzlich das Licht umschließen, aber auch keine Änderung.
  • Ok, es liegt an meiner Routine, die die Farben der Metaballs berechnet. Das Mischen der Farben in Abhängigkeit zur Gewichtung je nach Entfernung zum Mittelpunkt führt zu dunkleren Farben. Da muss ich nochmal eine bessere Routine schreiben für das Mischen. Danke fürs Mitdenken.
  • Die Beleuchtung hat aber nix mit der Farbgebung zu tun.
    Bedeutet selbst wenn Du die Farben abhängig von ihrer Position zum Mittelpunkt berechnest, sollte die Beleuchtung immer noch gleich sein.
  • Argh wieder rein gefallen, dreh mal die beiden um:
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);


    zu
    glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);

    glEnable(GL_COLOR_MATERIAL);
  • Mist, der Fehler scheint doch anders zu liegen. Es scheint irgendetwas bei den Metaballs nicht mit der Tiefendarstellung zu stimmen. Als ob der Depth-Test nicht funktioniert, obwohl ich den gar nicht ausschalte oder verändere. Es bleibt spannend.