簡體   English   中英

使用GLKit openGL - iOS繪制YUV圖像

[英]Draw YUV image using GLKit openGL - iOS

我想在iOS設備上渲染yuv圖像。 我認為可以使用openGL來實現。 (實際上我必須連續渲染多個這樣的圖像)

我理解的是,GLKit是iOS創建的一個抽象,其中有一個GLKView將擁有並處理渲染緩沖區。 我目前正在嘗試使用GLKViewController並且正在使用所需的fps成功完成幀更新。 這個我通過使用glClear函數調用。

現在的任務是在視圖上渲染圖像。

有一個類GLKBaseEffect ,它將具有基本着色器。 我無法弄清楚要設置的屬性,所以我只是創建它並在每次渲染之前調用prepareToDraw

有一個用於處理紋理的類, GLKTextureLoader ,但在我看來它只適用於Quartz圖像,即yuv420 plane無法使用此類加載到紋理中。

// create the texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, [imageNSData bytes]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);  

我使用此代碼生成紋理並綁定它,但我真的不知道我在這里嘗試做什么。 無論它是什么,它都不會在屏幕上顯示任何圖像,我不知道接下來該做什么。

我沒有創建任何着色器,假設baseEffect將有一些東西。

這個https://developer.apple.com/library/ios/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html#//apple_ref/doc/uid/TP40008793-CH103-SW8告訴我,我會有使用EAGLayer在屏幕上渲染圖像。

我可以使用GLKit渲染圖像嗎? 如果是,我們是否有任何不使用GLKTextureLoader類的示例代碼或教程(我找不到)? 如果沒有,是否有類似的使用EAGLLayer進行渲染的教程( EAGLLayer我還沒有探討過)?

聽起來你真的在這里詢問一些不同的主題:

  • 如何使用GLKViewCAEAGLLayer繪制
  • GLKBaseEffectGLKTextureLoader如何適用於OpenGL ES繪圖
  • 一旦有了紋理,如何繪制紋理
  • 如何渲染YUV圖像數據

我會嘗試依次解決每個問題......


GLKView適用於您想要做的任何OpenGL ES繪圖 - 它可以完成您鏈接的舊文檔所做的一切(為您設置framebuffers, CAEAGLLayer等),因此您不必編寫該代碼。 GLKView繪圖方法( drawRect:glkView:drawInRect:取決於您是否在子類或委托中繪圖)中,您編寫了與CAEAGLLayer (或任何其他系統)相同的OpenGL ES繪圖代碼。


您可以相互獨立地使用GLKViewGLKTextureLoaderGLKBaseEffect 如果要編寫所有自己的繪圖代碼並使用自己的着色器,可以在不使用GLKBaseEffect情況下繪制GLKView (您甚至可以混合和匹配GLKBaseEffect和您自己的東西,就像您在使用OpenGL游戲模板創建新的Xcode項目時所看到的那樣。)同樣, GLKTextureLoader加載圖像數據並吐出您需要的name來綁定它以進行繪制,無論您是否使用GLKBaseEffect繪制它,都可以使用它。


一旦獲得紋理,無論是通過GLKTextureLoader還是自己讀取/解碼數據並將其提供給glTexImage2D ,使用它繪制有三個基本步驟:

  1. 使用glBindTexture綁定紋理名稱。
  2. 繪制一些要紋理化的幾何體(使用glDrawArraysglDrawElements或類似物)
  3. 有一個片段着色器,可以查找紋素並輸出顏色。

如果您只想繪制填充視圖的圖像,只需繪制四邊形(兩個三角形)。 這是我想用於繪制全屏時使用一個四邊形設置頂點數組對象的代碼:

typedef struct __attribute__((packed)) {
    GLKVector3 position;
    GLKVector2 texcoord;
} Vertex;

static Vertex vertexData[] = {
    {{-1.0f,  1.0f, -1.0f}, {0.0f,  0.0f}},
    {{-1.0f, -1.0f, -1.0f}, {0.0f,  1.0f}},
    {{ 1.0f,  1.0f, -1.0f}, {1.0f,  0.0f}},
    {{ 1.0f, -1.0f, -1.0f}, {1.0f,  1.0f}},
};

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, texcoord));
glBindVertexArrayOES(0);

然后,繪制它:

glBindVertexArrayOES(_vertexArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

這只是幾何繪圖部分。 將它與GLKBaseEffect結合 - 其transform屬性是默認的標識轉換,其texture2d0屬性設置為您通過GLKTextureLoader或其他方式加載的紋理的name - 您將獲得一個視圖填充廣告牌你的紋理就可以了。


最后,YUV部分......我將大部分時間。 你在哪里獲得YUV紋理數據? 如果它來自設備相機,您應該查看CVOpenGLESTexture / CVOpenGLESTextureCache ,如本答案所述 無論如何,您應該能夠使用APPLE_rgb_422擴展來處理YUV紋理,如本答案所述 您還可以查看此答案,以獲得一些幫助編寫片段着色器以便在運行時將YUV處理為RGB。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM