Android OpenGL Kombination von SurfaceTexture (externes image) und normale textur
ich würde gerne mischen Kamera-Vorschau SurfaceTexture mit einigen overlay-textur. Ich bin mit diesen Shader für die Verarbeitung:
private final String vss = "attribute vec2 vPosition;\n"
+ "attribute vec2 vTexCoord;\n"
+ "varying vec2 texCoord;\n"
+ "void main() {\n"
+ " texCoord = vTexCoord;\n"
+ " gl_Position = vec4 ( vPosition.x, vPosition.y, 0.0, 1.0 );\n"
+ "}";
private final String fss = "#extension GL_OES_EGL_image_external : require\n"
+ "precision mediump float;\n"
+ "uniform samplerExternalOES sTexture;\n"
+ "uniform sampler2D filterTexture;\n"
+ "varying vec2 texCoord;\n"
+ "void main() {\n"
+" vec4 t_camera = texture2D(sTexture,texCoord);\n"
//+" vec4 t_overlayer = texture2D(filterTexture, texCoord);\n"
//+ " gl_FragColor = t_overlayer;\n" + "}";
+ " gl_FragColor = t_camera;\n" + "}";
Mein Ziel ist zu mischen t_camera und t_overlayer. Wenn ich zeige, t_camera oder t_overlayer getrennt, es funktioniert (zeigt Kamera-Vorschau oder textur). Aber wenn ich die Auskommentierung t_overlayer, dann t_camera wurde schwarz (irgendwie schlecht abgetastet). Mein Deckschicht textur ist 512x512 und CLAMPT_TO_EDGE.
Dieses problem tritt nur auf, zum Beispiel auf: Android-Emulator, HTC Evo 3D.
Aber auf SGS3, HTC One X, es funktioniert Prima.
Was ist falsch? Wird es Evo 3D fehlt, Erweiterung oder was?
- Sie erwähnt, dass es nicht funktioniert auf Android-Emulator. Welche OS-version hast du versucht? Haben Sie versucht, x86?
- Ich bin mit x64 emulator für MacOSX 10.8.2.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich mir vorstellen, dass Sie dieses problem haben, weil Sie nicht die richtige Einstellung textur-id, die auf Ihrem code. Dies ist eine typische Fehlermeldung, die auf Annahmen, die logisch erscheinen, aber ist eigentlich nicht definiert, so dass auf die Dokumentation. Wenn Sie überprüfen die Dokumentation zu dieser Erweiterung finden Sie in den folgenden (bearbeitet) TEXT:
Bedeutet dies, dass bei leas einem zusätzlichen arbeiten werden, vorausgesetzt, dass Sie mit id 0 für Sie. In deinem Fall:
Für Ihre 2D-textur:
Ich bin sicher, das wird Training für Sie.
Ich habe das gleiche Problem auf meinem Nexus 7 und es fuhr mich verrückt. Zugriff auf entweder eine samplerExternalOES oder eine sampler2D arbeitete völlig in Ordnung, aber der Zugriff auf Sie beide in der selben shader gab unerwartete Ergebnisse. Manchmal ist die Ausgabe wäre schwarz. Manchmal ist die Ausgabe von einem der lookup hätte schlechte Quantisierung Artefakte. Das Verhalten würde auch je auf die textur-Einheit mit den Samplern, wo gebunden. Ich habe mir jede opengl-Fehler und validateProgram Ergebnisse.
Schließlich, was funktionierte, war der Einsatz einer separaten shader einfach auf die Kamera-Ausgabe und Rendern in eine textur. Dann wird die resultierende textur kann durch eine regelmäßige sampler2D und alles funktioniert genau wie erwartet. Ich vermute da ist ein Fehler irgendwo im Zusammenhang zu samplerExternalOES.
Die Methode auf die oben genannten speichern viel von meiner Zeit. Danke guru:
Für Ihre 2D-textur:
Ändern Sie die textur-index ist eine gute Möglichkeit, dies zu lösen.
Es scheint ein bug im OpenGl-Implementierung. Der gleiche code funktionierte gut auf dem Samsung Note und nicht auf dem nexus 4. Es scheint, dass getUniformLocation bricht bei einigen Geräten, die für alle Variablen, die sich letzten samplerExternalOES.
es scheint auch, dass compiler-Art uniform-Variablen alphabeticaly, so ist die Lösung, dass es funktioniert auf beiden Geräten wurde umbenannt samplerExternalEoz werden zzzTexture oder so etwas.
Dies ist nicht eine Antwort, sondern eine Ausarbeitung der Frage - vielleicht wird es Ihnen helfen, eine OpenGl-ES-Experte, um eine Vorstellung von dem problem.
Ich habe 3 Texturen verwendet, die für overlay, und eine externe textur, verwendet, um zu erfassen, Ausgabe vom media-player. Wenn ich nur externe textur, die Ausgabe ist wie erwartet, frames von MPlayer. Den gleichen code funktioniert gut auf Nexus4, Samsung Galaxy S3, S4, etc. (alle Geräte verwenden entweder adreno gpus, oder Arm Mali400) Der Unterschied in der hardware ist das Nexus 7 nutzt Nvidia Tegra 3 board.
Bearbeiten (wie war gelöst auf meiner Seite):
Nvidia Tegra 3 muss die externe textur-sampler-Aufruf ein name mit niedrigsten alphabetischen Reihenfolge unter den Samplern, während die Adreno 220 scheinen das Gegenteil. Auch T3 erfordern, dass die externe textur gesampelt wird letzten. Bei Geräten mit Android 4.3 und neuere Versionen, die diese Fehler beseitigt werden können. Auf Nvidia-Seite, es war ein Fehler, vor langer Zeit gelöst aber Nexus Treiber aktualisiert wurden, nur später. Ich hatte also zu prüfen, welche gpu vorhanden war, und den code entsprechend anpassen.
Bezogen auf user1924406 post (https://stackoverflow.com/a/14050597/3250829) auf aufteilen der Zugriff auf eine sampler2D textur und samplerExternalOES textur, dies ist, was ich zu tun hatte, weil die Anwendung, die ich entwickle, ist das Lesen aus einer Datei oder streaming von einem server statt der Verwendung der Kamera, auf dem Gerät. Mit beiden Texturen in den gleichen shader führte zu sehr komischen colourization Artefakte (der Fall ist auf einem Galaxy-S3) oder Sättigung und Kontrast Probleme (der Fall ein Nexus 4).
Als solche, die einzige Möglichkeit zum umgehen der samplerExternalOES textur-bug (von dem, was ich bisher gesehen habe) zu tun, die beiden shader-Programme: Eines, das schreibt die Inhalte in die samplerExternalOES textur in einem FBO und die andere, dass der Inhalt von der FBO und schreibt es direkt auf die Oberfläche.
Eine Sache, die Sie brauchen zu prüfen, ist, dass manchmal, wenn Sie schreiben, um einen FBO, die textur-Koordinaten zu spiegeln. In meinem Fall, die V (oder T oder Y) co-ordinate gespiegelt wurde, was zu einer gespiegelten Bild über die horizontale Achse. Ich hatte, um dies zu berücksichtigen, wenn das schreiben der fragment-shader auf der zweiten Stufe.
Dies ist ein Krieg-Geschichte, die ich wollte zu teilen, falls es einige von Euch, die Lesen müssen, aus einer Datei oder einem stream von einem server statt direkt von der Kamera.
Vielleicht habe ich das gleiche problem. nach Tagen versuchen, ich bin schlägt meine Lösungen hier. In der Hoffnung dies würde den anderen helfen.
Erstens, die Problematik. wie Lukáš Jezný, ich habe ein Album Vorhören textur und eine overlay-textur. es funktioniert gut für das nexus 4/5 und die meisten anderen Arten, zeigt aber nichts auf dem OPPO find 5, Lenovo A820, Lenovo A720.
Lösung:
(1)wie Lukáš Jezný, verwenden Sie YUV-Daten und die Umwandlung an den RGB-in den shader.
(2)multipass-Zeichnung, ziehen Sie die Vorschau der textur in den framebuffer einmal , und Lesen Sie es, dann ziehen Sie es wieder auf den Bildschirm.
(3)ein anderes Programm verwenden, bevor Sie mit Ihrem eigenen Programm,
und es funktioniert einfach für OPPO find 5, Lenovo A820, Lenovo A720 und andere. Niemand weiß, warum......
In Ordnung, zum konvertieren einer externen textur (nicht die GPU), um eine regelmäßige interne, müssen Sie
GLES20.GL_TEXTURE_2D
mitGLES11Ext.GL_TEXTURE_EXTERNAL_OES
).SurfaceTexture
mit dem externen textur.onFrameAvailable
des SurfaceTexture und führen Sie die Konvertierung hier liefert sowohl die externe textur zu Lesen, und die innere textur zu schreiben.getTransformMatrix
für Korrekturen der Koordinaten (meist flip y-Achse) und stellen Sie es als gut. Manchmal nicht...hier einige Beispiel-Shader:
Vertex-shdaer -
Fragment-shader -