3 Stimmen

Color Picking mit AntiAliasing in OpenGL?

Ich habe ein Problem mit Farbauswahl und Antialiasing in OpenGL. Wenn AA aktiviert ist, sind die Ergebnisse von glReadPixels offensichtlich falsch an Objektkanten und Objektschnittpunkten. Zum Beispiel:

Ich rendere eine Box #28 (RGBA: 28, 0, 0, 0) neben einer Box #32 (RGBA: 32, 0, 0, 0). Mit AA kann ich einen falschen ReadPixel-Wert (z.B. 30) erhalten, wo der Würfel und das Dreieck überlappen, oder einen Wert von 14 auf Boxen Rand, aufgrund der AA-Algorithmus.

Ich habe ~4000 tausend Objekte, die ich auswählen können muss (es ist ein Puzzlespiel). Es ist wichtig, Objekte nach Form auswählen zu können.

Ich habe versucht, AA mit glDisable(GL_MULTISAMPLE) zu deaktivieren, aber es funktioniert nicht mit bestimmten AA-Modi (ich habe gelesen, dass es von der AA-Implementierung abhängt - SS, MS, CS )

Wie wähle ich also ein zugrunde liegendes Objekt aus?

  1. Eine Möglichkeit, AA vorübergehend zu deaktivieren?
  2. Verwenden Sie einen anderen Puffer oder sogar einen anderen Rendering-Kontext?
  3. Haben Sie einen anderen Vorschlag?

7voto

Christian Rau Punkte 44134

Warum nicht einen FBO als Puffer für Ihre Abholung nutzen?

2voto

Giumo Punkte 339

Ich verwende diesen Hack: Ich wähle nicht nur ein Pixel, sondern alle 3x3=9 Pixel rund um den Auswahlpunkt. Wenn sie alle gleich sind, sind wir sicher. Andernfalls muss der Punkt am Rand liegen und wir können ihn überspringen.

int renderer::pick_(int x, int y)
{
    static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
            "only works on little-endian architecture");
    static_assert(sizeof(int) == 4,
            "only works on architecture that has int size of 4");

    // sort of edge detection. selection only happens at non-edge
    // since the edge may cause anti-aliasing glitch
    int ids[3*3];
    glReadPixels(x-1, y-1, 3, 3, GL_RGBA, GL_UNSIGNED_BYTE, ids);
    for (auto& id: ids) id &= 0x00FFFFFF;       // mask out alpha
    if (ids[0] == 0x00FFFFFF) return -1;        // pure white for background

    // prevent anti-aliasing glitch
    bool same = true;
    for (auto id: ids) same = (same && id == ids[0]);
    if (same) return ids[0];

    return -2;                                  // edge
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X