Kann ich in OpenGL ein Pixel genau an den Koordinaten (5, 5) zeichnen?
Lesezeit: 6 Minuten
xzhu
Mit (5, 5) meine ich genau die fünfte Zeile und fünfte Spalte.
Ich fand es sehr schwierig, Dinge mithilfe von Bildschirmkoordinaten zu zeichnen, da alle Koordinaten in OpenGL relativ sind und normalerweise zwischen -1,0 und 1,0 liegen. Warum ist es so ernst, Programmierer daran zu hindern, Bildschirmkoordinaten/Fensterkoordinaten zu verwenden?
Weil es verwendet wird [-1..1] anstatt [0..800] Funktioniert auch mit einem 1024p-Bildschirm. Aber seit Du Kennen Sie die Größe Ihres Bildschirms und befolgen Sie die Anweisungen von Datenwolf und Basszero.
– Calvin1602
27. Mai 2011 um 23:18
OpenGL ist das, was passiert, wenn Informatikstandards von Mathematikern entworfen werden. Wenn CS-Leute und UX-Leute dort wären, würden sie einfache Funktionen zum Festlegen der Auflösung, des Textmodus und der Fähigkeit enthalten Zeichne dünne Linien mit Subpixel-Präzision aus der Box.
Thankkkkk youuuuu! Es scheint, als ob das Internet darüber schweigt.
– Andreas
1. April 2017 um 17:13 Uhr
basszero
Der einfachste Weg besteht wahrscheinlich darin, die Projektion so einzustellen, dass sie mit den Pixelabmessungen des Renderraums übereinstimmt glOrtho. Dann können Scheitelpunkte in Pixelkoordinaten angegeben werden. Der Nachteil besteht darin, dass die Größenänderung des Fensters Probleme verursachen kann und Sie die beschleunigten Transformationen größtenteils verschwenden.
Angenommen, ein Fenster ist 640 x 480 groß:
// You can reverse the 0,480 arguments depending on you Y-axis
// direction preference
glOrtho(0, 640, 0, 480, -1, 1);
Frame-Puffer-Objekte und Texturen sind eine weitere Möglichkeit, aber Sie müssen Ihre eigenen Rasterungsroutinen erstellen (Linie, Kreis, Bitmap usw. zeichnen). Dafür gibt es wahrscheinlich Bibliotheken.
Fast zehn Jahre später sollte dies jedoch die akzeptierte Antwort sein.
– z0rbergs
11. Dezember 2020 um 19:08 Uhr
J. Guarin
@dandan78 OpenGL ist kein Vektorgrafik-Renderer. Ist ein Rasterizer. Genauer gesagt handelt es sich um einen Standard, der mithilfe einer C-Sprachschnittstelle beschrieben wird. Ein Rasterizer ordnet Objekte, die in 3D-koordinierten Räumen dargestellt werden (ein Auto, ein Baum, eine Kugel, ein Drache), in 2D-koordinierte Räume (z. B. eine Ebene, Ihr App-Fenster oder Ihre Anzeige) zu. Diese 2D-Koordinaten gehören zu einer diskreten koordinierten Ebene. Die Gegendarstellungsmethode der Rasterung ist Ray Tracing.
Vektorgrafiken sind eine Möglichkeit, mithilfe mathematischer Funktionen eine Reihe von Kurven, Linien oder ähnlichen geometrischen Grundelementen auf nichtdiskrete Weise darzustellen. Daher befinden sich Vektorgrafiken im Bereich „Modelldarstellung“ und nicht im Bereich „Rendering“.
Christian Rau
Sie können einfach die „Kamera“ ändern, damit 3D-Koordinaten mit den Bildschirmkoordinaten übereinstimmen, indem Sie die Modellansichtsmatrix auf „Identität“ und die Projektion auf eine orthographische Projektion setzen (siehe meine Antwort auf diese Frage). Dann können Sie einfach ein einzelnes Punktgrundelement an den erforderlichen Bildschirmkoordinaten zeichnen.
Sie können die Rasterposition auch mit festlegen glWindowPos (was im Gegensatz dazu in Bildschirmkoordinaten funktioniert glRasterPos) und dann einfach verwenden glDrawPixels um ein 1×1 Pixel großes Bild zu zeichnen.
glEnable( GL_SCISSOR_TEST );
glScissor( 5, 5, 1, 1 ); /// position of pixel
glClearColor( 1.0f, 1.0f, 1.0f, 0.0f ); /// color of pixel
glClear( GL_COLOR_BUFFER_BIT );
glDisable( GL_SCISSOR_TEST );
Durch Ändern der letzten beiden Argumente von glScissor können Sie auch ein pixelgenaues Rechteck zeichnen.
dandan78
Ich habe mich vor einigen Jahren ein wenig mit 3D-Programmierung beschäftigt und obwohl ich alles andere als ein Experte bin, denke ich, dass Sie einen sehr wichtigen Unterschied zwischen klassischer Bitmap-Programmierung übersehen DrawPixel(x, y) Grafiken und die Art der mit Direct3D und OpenGL erstellten Grafiken.
In den Tagen vor 3D ging es bei der Computergrafik hauptsächlich um Bitmaps, also um Ansammlungen farbiger Punkte. Diese Punkte hatten eine 1:1-Beziehung zu den Pixeln auf Ihrem Monitor.
Dies hatte jedoch zahlreiche Nachteile, unter anderem machte es 3D sehr schwierig und erforderte Bitmaps unterschiedlicher Größe für unterschiedliche Anzeigeauflösungen.
In OpenGL/D3D haben Sie es mit Vektorgrafiken zu tun. Linien werden durch Punkte in einem dreidimensionalen Koordinatenraum definiert, Formen werden durch Linien usw. definiert. Oberflächen können Texturen aufweisen, Lichter können hinzugefügt werden, ebenso wie verschiedene Arten von Lichteffekten usw. Diese gesamte Szene oder ein Teil davon kann dann durch eine virtuelle Kamera betrachtet werden.
Was Sie durch diese virtuelle Kamera „sehen“, ist eine Projektion der Szene auf eine 2D-Oberfläche. An dieser Stelle beschäftigen wir uns noch mit Vektorgrafiken. Da Computeranzeigen jedoch aus einzelnen Pixeln bestehen, muss dieses Vektorbild gerastert werden, wodurch der Vektor in eine Bitmap mit tatsächlichen Pixeln umgewandelt wird.
Zusammenfassend lässt sich sagen, dass Sie keine Bildschirm-/Fensterkoordinaten verwenden können, da OpenGL auf Vektorgrafiken basiert.
Wer rastert dann die von OpenGL verarbeiteten Vektordaten? Wenn es sich um OpenGL selbst handelt, sollte es meiner Meinung nach zumindest ein paar APIs übrig lassen, die es den Benutzern ermöglichen, das Endergebnis leicht zu modifizieren, oder besser gesagt, ein Fenster zu lassen, in dem Benutzer die Pixelpuffer lesen/schreiben können.
– xzhu
27. Mai 2011 um 11:37
Sie können ein Frame-Buffer-Objekt zuweisen, Ihre Szene darin rendern und dann alle gewünschten Pixel-Painting-Aufgaben damit ausführen.
– n0rd
27. Mai 2011 um 11:41
Abgesehen davon ist es wirklich einfach, OpenGL-Koordinaten den Ansichtsfensterkoordinaten zuzuordnen: glViewport(win_offset_x, win_offset_y, win_width, win_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(win_offset_x, win_offset_x+win_width, win_offset_y, win_offset_y+win_height, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); et voila, OpenGL-Koordinaten werden jetzt den Pixelkoordinaten des Ansichtsfensters zugeordnet.
– datenwolf
27. Mai 2011 um 13:28
Wow, DAS war die akzeptierte Antwort? Es wurde nicht einmal die Frage beantwortet, sondern nur gesagt: „Was Sie versuchen, ist unmöglich“, was eine glatte Lüge ist.
– Andreas
1. April 2017 um 17:15 Uhr
Diese Antwort und die Tatsache, dass irgendjemand sie positiv bewertet hat, macht mich wirklich wütend.
– Andreas
1. April 2017 um 17:17 Uhr
Ich weiß, dass ich sehr spät zur Party komme, aber nur für den Fall, dass in Zukunft jemand diese Frage hat. Ich habe die Bildschirmkoordinaten wie folgt in OpenGL-Matrixkoordinaten umgewandelt:
Dabei handelt es sich im Grunde um Neuskalierungsmethoden.
Wer rastert dann die von OpenGL verarbeiteten Vektordaten? Wenn es sich um OpenGL selbst handelt, sollte es meiner Meinung nach zumindest ein paar APIs übrig lassen, die es den Benutzern ermöglichen, das Endergebnis leicht zu modifizieren, oder besser gesagt, ein Fenster zu lassen, in dem Benutzer die Pixelpuffer lesen/schreiben können.
– xzhu
27. Mai 2011 um 11:37
Sie können ein Frame-Buffer-Objekt zuweisen, Ihre Szene darin rendern und dann alle gewünschten Pixel-Painting-Aufgaben damit ausführen.
– n0rd
27. Mai 2011 um 11:41
Abgesehen davon ist es wirklich einfach, OpenGL-Koordinaten den Ansichtsfensterkoordinaten zuzuordnen: glViewport(win_offset_x, win_offset_y, win_width, win_height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(win_offset_x, win_offset_x+win_width, win_offset_y, win_offset_y+win_height, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); et voila, OpenGL-Koordinaten werden jetzt den Pixelkoordinaten des Ansichtsfensters zugeordnet.
– datenwolf
27. Mai 2011 um 13:28
Wow, DAS war die akzeptierte Antwort? Es wurde nicht einmal die Frage beantwortet, sondern nur gesagt: „Was Sie versuchen, ist unmöglich“, was eine glatte Lüge ist.
– Andreas
1. April 2017 um 17:15 Uhr
Diese Antwort und die Tatsache, dass irgendjemand sie positiv bewertet hat, macht mich wirklich wütend.
– Andreas
1. April 2017 um 17:17 Uhr
14525300cookie-checkKann ich in OpenGL ein Pixel genau an den Koordinaten (5, 5) zeichnen?yes
Weil es verwendet wird [-1..1] anstatt [0..800] Funktioniert auch mit einem 1024p-Bildschirm. Aber seit Du Kennen Sie die Größe Ihres Bildschirms und befolgen Sie die Anweisungen von Datenwolf und Basszero.
– Calvin1602
27. Mai 2011 um 23:18
OpenGL ist das, was passiert, wenn Informatikstandards von Mathematikern entworfen werden. Wenn CS-Leute und UX-Leute dort wären, würden sie einfache Funktionen zum Festlegen der Auflösung, des Textmodus und der Fähigkeit enthalten Zeichne dünne Linien mit Subpixel-Präzision aus der Box.
– anatoli techtonik
10. April 2013 um 12:11 Uhr
stackoverflow.com/questions/5467218/opengl-2d-hud-over-3d
– Ciro Santilli OurBigBook.com
12. April 2016 um 10:53
Thankkkkk youuuuu! Es scheint, als ob das Internet darüber schweigt.
– Andreas
1. April 2017 um 17:13 Uhr