Wie würdet ihr ein Rechteck mit runden Ecken in OpenGL umsetzen?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Wie würdet ihr ein Rechteck mit runden Ecken in OpenGL umsetzen?

    Hi Leute,

    wie würdet Ihr das Zeichnen eines Rechtecks mit abgerundeten Ecken mittels OpenGL umsetzen? Im Grunde benötige ich ein Equivalent zu NSBezierPaths +bezierPathWithRoundedRect:xRadius:yRadius:. Als Trianglefan, also die Rundungen mit Vertexen modellieren oder als Alpha-Textur (mit Alpha-Wert 0 ausserhalb der runden Ecken)? Im Netz habe ich diverse Anhaltspunkte gefunden für beide Umsetzungen u.a. das hier: stackoverflow.com/questions/53…-1-0-2d-rounded-rectangle

    Ich benötige das in einem reinen C++ Projekt, welches auf verschiedenen Plattformen benötigt wird, CG/Cocoa kann ich nicht verwenden. Der Renderer ist OpenGL3 basiert, die glu/legacy OpenGL-Sachen scheiden daher leider aus.

    Danke für Euere Zeit, Gruß, Markus
  • Mit Trianglefan, genau wie bei SO beschrieben. Dann kannst Du es auch später noch beliebig skalieren.

    Alternativ: Am Bild auf SO orientiert:
    4 vertices vom mittleren Rechteck plus alle Vertices vom Rand in ein VBO und dann normal TRIANGLE über Indizes (in einem zweiten Buffer-Objekt). So kannst Du alles in "einem Rutsch" rendern. Ist ja dort auch vorgeschlagen, kannst Dir ja auch ein grosses Triangle-Strip draus bauen.

    Sonst vielleicht noch unterteilen in 9 Rechtecke und die Runden kanten im Geometry-Shader für 4 dieser 9 Recktecke generieren, aber ich denke das wird nichts "extra" bringen. Ausser "coolness" vielleicht :P

    Mhhh a propos "coolness": Kannst ja auch OpenGL 4 nehmen, das ganze als Bezier-Fläche modellieren und im Tess-Shader triangulieren :D

    EDIT:
    Vielleicht auch gar nicht so verkehrt und recht "lazy": Das ganze in Blender/Maya modellieren, dann trianguliert er es Dir hoffentlich auch schön damit die Winkel optimal sind, und dann einfach die Vertices/TexCoords exportieren und in Deiner App verwenden. Gar nicht so übel, dann kannst Du (oder sonst wer) die Vorlage in Maya einfach bei Bedarf ändern und der Code bleibt so, wie er ist...
    Die paar Vertices/TCs laden oder meinetwegen auch hard-coded in einem C-File sollten Dich nix kosten...
    C++

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von zerm ()

  • Danke, zerm.

    Hatte auch überlegt, das mit dem GS zu machen, aber das ist wahrscheinlich mit Kanonen auf Spatzen schießen (benötige das nur als 2D fürs UI wie in Aqua) . Der einfachste und eleganteste Weg wird wohl der mit Blender sein, da hab ich den Wald vor lauter Bäumen nicht gesehen...

    Edit:
    Der GS ist wohl bei Mac OS unter ATI-Hardware software-only, rate mal, was für eine Graka ich habe...
  • Markus Müller schrieb:

    Der GS ist wohl bei Mac OS unter ATI-Hardware software-only, rate mal, was für eine Graka ich habe...

    Die Spinner mit ihrer LLVM. Ist ja toll, dass damit so fetzige sachen gehen, aber ich habe bis heute nicht herausgefunden, wie man prüfen kann, ob ein Feature nativ oder emuliert abläuft. Die sollten sich mal lieber um vollständige OpenGL 3.x Compliance kümmern und langsam mal 4.x angehen.....ach

    Ist aber wohl ein älterer Rechner? GS sollten inzwischen doch bei allem, was jünger ist als vielleicht 3 Jahre Standard sein?!
    C++
  • zerm schrieb:

    Markus Müller schrieb:

    Der GS ist wohl bei Mac OS unter ATI-Hardware software-only, rate mal, was für eine Graka ich habe...

    Die Spinner mit ihrer LLVM. Ist ja toll, dass damit so fetzige sachen gehen, aber ich habe bis heute nicht herausgefunden, wie man prüfen kann, ob ein Feature nativ oder emuliert abläuft. Die sollten sich mal lieber um vollständige OpenGL 3.x Compliance kümmern und langsam mal 4.x angehen.....ach

    Ist aber wohl ein älterer Rechner? GS sollten inzwischen doch bei allem, was jünger ist als vielleicht 3 Jahre Standard sein?!

    Nein, ganz im Gegenteil. Ich habe es nicht überprüft, aber ein Apple-Ingenieur hat genau das im Developerforum geschrieben ("is under heavy work"). Unter Windows gehts...
  • So, hab mir das fix selbst geschrieben, ist wirklich super simpel (mit ein wenig Nachdenken :D )

    Hier der eigentliche Code:

    Quellcode

    1. typedef struct _point
    2. {
    3. float x;
    4. float y;
    5. } point;
    6. static void drawRoundedRect( float radius, float x, float y, float width, float height, int steps )
    7. {
    8. point center;
    9. center.x = x + width / 2.f;
    10. center.y = y + height / 2.f;
    11. float top = y + height;
    12. float bottom = y;
    13. float left = x;
    14. float right = x + width;
    15. point corners[4];
    16. // rechts oben
    17. corners[0].x = right - radius;
    18. corners[0].y = top - radius;
    19. // rechts unten
    20. corners[1].x = right - radius;
    21. corners[1].y = bottom + radius;
    22. // links unten
    23. corners[2].x = left + radius;
    24. corners[2].y = bottom + radius;
    25. // links oben
    26. corners[3].x = left + radius;
    27. corners[3].y = top - radius;
    28. float angle = 0;
    29. // jeweils um 90 Grad rotieren
    30. float delta = 90.f / steps;
    31. glBegin( GL_TRIANGLE_FAN );
    32. glVertex2f( center.x, center.y );
    33. for ( int i = 0; i < 4; ++i ) {
    34. point & rotationPoint = corners[ i ];
    35. // curve
    36. for ( int j = 0; j < steps; ++j ) {
    37. float anglerad = M_PI * angle / 180.f;
    38. glVertex2f( rotationPoint.x + sinf(anglerad) * radius, rotationPoint.y + cosf(anglerad) * radius );
    39. angle += delta;
    40. }
    41. }
    42. glVertex2f( corners[0].x, top );
    43. glEnd();
    44. }
    Alles anzeigen

    Im Anhang ein kleines GLUT-basiertes Beispielprojekt. Nochmals Danke für Eure Tips,

    Gruß, Markus

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Markus Müller ()