[英]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
我還沒有探討過)?
聽起來你真的在這里詢問一些不同的主題:
GLKView
和CAEAGLLayer
繪制 GLKBaseEffect
和GLKTextureLoader
如何適用於OpenGL ES繪圖 我會嘗試依次解決每個問題......
GLKView
適用於您想要做的任何OpenGL ES繪圖 - 它可以完成您鏈接的舊文檔所做的一切(為您設置framebuffers, CAEAGLLayer
等),因此您不必編寫該代碼。 在GLKView
繪圖方法( drawRect:
或glkView:drawInRect:
取決於您是否在子類或委托中繪圖)中,您編寫了與CAEAGLLayer
(或任何其他系統)相同的OpenGL ES繪圖代碼。
您可以相互獨立地使用GLKView
, GLKTextureLoader
和GLKBaseEffect
。 如果要編寫所有自己的繪圖代碼並使用自己的着色器,可以在不使用GLKBaseEffect
情況下繪制GLKView
。 (您甚至可以混合和匹配GLKBaseEffect
和您自己的東西,就像您在使用OpenGL游戲模板創建新的Xcode項目時所看到的那樣。)同樣, GLKTextureLoader
加載圖像數據並吐出您需要的name
來綁定它以進行繪制,無論您是否使用GLKBaseEffect
繪制它,都可以使用它。
一旦獲得紋理,無論是通過GLKTextureLoader
還是自己讀取/解碼數據並將其提供給glTexImage2D
,使用它繪制有三個基本步驟:
glBindTexture
綁定紋理名稱。 glDrawArrays
, glDrawElements
或類似物) 如果您只想繪制填充視圖的圖像,只需繪制四邊形(兩個三角形)。 這是我想用於繪制全屏時使用一個四邊形設置頂點數組對象的代碼:
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.