iOS GLKit:Stellen Sie die GLKBaseEffect-Textur mit der Kameraausgabe ein
-
20-12-2019 - |
Frage
Ich habe eine AVCapture-Sitzung eingerichtet und verwende in der Delegate-Methode den folgenden Code, um zu versuchen, eine GLKBaseEffect-Textur mit der Ausgabe festzulegen. Ich erhalte jedoch nur Schwarz.Was muss ich tun, damit es funktioniert?
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer (CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
effect.texture2d0.name = CVOpenGLESTextureGetName(pixelBuffer);
}
Lösung
TLDR: Ich glaube nicht, dass man die Kameraausgabe mit verwenden kann GLKBaseEffect
– Daten von der Kamera liegen im biplanaren YUV-Format vor, daher benötigen Sie einen benutzerdefinierten Fragment-Shader, um diese beim Rendern in RGB zu konvertieren, und GLKBaseEffect
führt keine benutzerdefinierten Shader durch.
Es sieht so aus, als gäbe es hier eine gewisse API-Verwirrung. Lesen Sie also weiter, wenn Sie mehr Hintergrundinformationen wünschen ...
Obwohl die CVOpenGLESTexture
Typ ist abgeleitet von CVPixelBuffer
, die Bildpuffer, von denen Sie zurückkommen CMSampleBufferGetImageBuffer
sind nicht automatisch OpenGL ES-Texturen.Sie müssen jedes Mal, wenn Sie ein Bild von der Kamera erhalten, Texturen aus Bildpuffern erstellen CVOpenGLESTextureCache
.
Äpfel GLCameraRipple
Beispielcode veranschaulicht, wie das geht.Hier ein kurzer Überblick:
- Nach dem Einrichten eines GL-Kontexts wird der
setupAVCapture
MethodenaufrufeCVOpenGLESTextureCacheCreate
um einen Textur-Cache zu erstellen, der an diesen Kontext gebunden ist. - In
captureOutput:didOutputSampleBuffer:fromConnection:
, holen sie sich den Bildpuffer aus dem Beispielpuffer mitCMSampleBufferGetImageBuffer
, und erstellen Sie dann mithilfe der Textur-Caches daraus zwei OpenGL ES-TexturenCVOpenGLESTextureCacheCreateTextureFromImage
Funktion.Sie benötigen zwei Texturen, da der Bildpuffer YUV-Farbdaten in zwei Bitebenen enthält. - Jede Textur wird direkt nach der Erstellung mit zum Rendern gebunden
glBindTexture
.Im Allgemeinen könnten Sie a ersetzenglBindTexture
Anruf mit Einstellung aGLKBaseEffect
'Stexture2d0.name
und sag esprepareToDraw
, AberGLKBaseEffect
YUV kann nicht gerendert werden. - Zeichnen Sie mit den beiden gebundenen Texturen und verwenden Sie dazu ein Shader-Programm, dessen Fragment-Shader zunächst einen YUV-Vektor erstellt, indem er Komponenten aus den Y- und UV-Texturen kombiniert, und dann eine einfache Matrixmultiplikation durchführt, um ihn gemäß der HDTV-Farbraumspezifikation in eine RGB-Pixelfarbe umzuwandeln .
Da Sie für die Konvertierung von YUV in RGB einen benutzerdefinierten Fragment-Shader benötigen, GLKBaseEffect
wird dir nicht helfen.Allerdings wie die GLCameraRipple
Beispiel zeigt, dass die benutzerdefinierten Shader, die Sie schreiben müssten, nicht so beängstigend sind.