Ihre Frage scheint bestimmte Konzepte zu verwirren. Nehmen wir also die Dinge von oben. Dies ist die Definition der Funktion glTexImage2D
:
void glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, void *data );
Es gibt zwei Dinge, die Sie als "Texturformate" bezeichnen könnten. Der erste ist der internalformat
Parameter. Dies ist das tatsächliche Format des Bildes, wenn OpenGL es speichert. Der format
Parameter beschreibt einen Teil des Formats der Pixeldaten, die Sie mit dem data
Parameter bereitstellen .
Anders ausgedrückt format
und type
definieren Sie, wie Ihre Daten aussehen. internalformat
So weisen Sie OpenGL an , Ihre Daten zu speichern . Nennen wir format
und type
das "Pixelübertragungsformat", während internalformat
das "Bildformat" sein wird.
Das Bildformat einer Textur kann niemals "bgr8" sein. Es gibt keinen GL_BGR8-Bildformat-Enumerator. Es gibt eine GL_BGR-Aufzählung, aber das gilt für das Pixelübertragungsformat, nicht für das Bildformat.
Oder anders ausgedrückt: Ihre Pixeldaten, die Sie OpenGL geben, können in der BGR-Reihenfolge gespeichert werden. Die OpenGL-Implementierung entscheidet jedoch selbst, wie diese Pixeldaten tatsächlich gespeichert werden. Vielleicht speichert es es in Little-Endian-Reihenfolge. Vielleicht speichert es Big-Endian. Vielleicht ordnet es die Bytes nur willkürlich neu. Sie wissen es nicht und OpenGL bietet keine Möglichkeit, dies herauszufinden.
Es kann nicht festgestellt werden, ob ein bestimmter Satz von Parametern für das Pixelübertragungsformat mit der Art und Weise übereinstimmt, in der die OpenGL-Implementierung sie angesichts des Bildformats speichert.
Es gibt eine Möglichkeit , dies jetzt zu sagen. Und mit "jetzt" meine ich in OpenGL 4.3 und / oder ARB_internalformat_query2. Kommen zu einer Grafikkarte in Ihrer Nähe:
GLenum format, type;
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_FORMAT, 1, &format);
glGetInternalformativ(texture_target, GL_RGBA8, GL_TEXTURE_IMAGE_TYPE, 1, &type);
format
und type
jetzt haben die Implementierung bevorzugt format
und type
für die Verwendung von glTex(Sub)Image
Aufrufen zu GL_RGBA8
Bildern. Es gibt separate format
und type
Abfragen zum glReadPixels
Herunterladen.
Es gibt andere Fragen, die Sie stellen können .
Wenn Sie keinen Zugriff auf diese haben, können Sie einige allgemeine Faustregeln verwenden, die von der meisten Hardware eingehalten werden:
- speichert Pixeldaten für 8-Bit-pro-Kanal-Daten in BGRA-Reihenfolge. Wenn Sie also das Format mit Ihren Pixeldaten abgleichen möchten, um Texturdaten schneller hochzuladen, möchten Sie es
GL_BGRA
für das format
und GL_UNSIGNED_INT_8888
oder GL_UNSIGNED_BYTE
für das verwenden type
.
- speichert 24-Bit-Farben nicht als 24-Bit. Sie werden immer auf 32 Bit aufgefüllt. Das Alpha wird beim Lesen der Daten einfach ignoriert. Wenn Sie also Formate abgleichen möchten, verwenden Sie diese immer
GL_BGRA
format
mit GL_RGB8
Bildformaten, auch wenn Sie Dummy-Daten in die Alpha-Komponente einfügen müssen.
Im Allgemeinen unterstützt die meiste Hardware keine 3-Komponenten-Texturformate. In diesem Beispiel können Sie also davon ausgehen, dass sie konvertiert wurde. Eine 3-Komponenten-OpenGL-Textur besteht in der Hardware aus 4 Komponenten, wobei die Alpha-Komponente ignoriert / auf 255 / was auch immer gesetzt wird.
https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads (Diese Seite "Häufige Fehler" ist eine Goldmine - bookmarken Sie sie jetzt!)
Für einen allgemeineren Fall kann die Leistung von glTexSubImage2D einen guten Hinweis darauf geben, ob der Upload einen Softwarekonvertierungspfad durchlaufen muss oder nicht. Sie würden dies während des Programmstarts tun - erstellen Sie einfach eine leere Textur (über glTexImage2D mit NULL-Daten) und geben Sie dann eine Reihe von glTexSubImage2D-Aufrufen aus, denen jeweils ein glFinish folgt, um sicherzustellen, dass der Vorgang abgeschlossen ist. Ignorieren Sie den ersten, da dafür Caches / States / etc eingerichtet werden, und planen Sie den Rest. Wiederholen Sie diesen Vorgang für einige verschiedene Formate und wählen Sie das schnellste aus.
Eine andere Alternative - da Sie diese Frage mit "Windows" markiert haben - besteht darin, beim Start ein D3D-Gerät zu erstellen (direkt nachdem Sie Ihr Fenster erstellt haben, aber bevor Sie OpenGL starten) und dann mit D3D nach Formatunterstützung zu suchen. Während OpenGL die Konvertierung von Software in ein gültiges internes Format ermöglicht, ist dies bei D3D nicht der Fall - wenn es nicht von der Hardware unterstützt wird, können Sie dies nicht tun. Dann zerstöre D3D und rufe OpenGL auf. (Diese Technik kann auch zum Abfragen anderer Dinge verwendet werden, die OpenGL nicht direkt abfragen lässt.)
Es ist eine nützliche Faustregel, um zu überprüfen, was Sie in OpenGL mit der D3D-Dokumentation tun. Wenn D3D etwas nicht kann, kann dies ein guter Hinweis darauf sein, dass das betreffende Objekt in der Hardware nicht unterstützt wird. Nicht immer wahr, aber ein nützlicher Ausgangspunkt.
quelle