2013-05-12 155 views
5

我正在嘗試對圖像文件進行一些OpenGL ES 2.0渲染,而不依賴於屏幕上向用戶顯示的渲染。我要呈現的圖像與用戶的屏幕大小不同。我只需要一個GL_RGB數據的字節數組。我熟悉glReadPixels,但我不認爲它會在這種情況下做到這一點,因爲我沒有從已經渲染的用戶屏幕拉出。將OpenGL ES 2.0渲染爲圖像

僞代碼:

// Switch rendering to another buffer (framebuffer? renderbuffer?) 

// Draw code here 

// Save byte array of rendered data GL_RGB to file 

// Switch rendering back to user's screen. 

我怎麼能做到這一點,而無需中斷用戶的顯示?我寧願不必閃爍用戶的屏幕,爲單個幀繪製我想要的信息,glReadPixel-ing,然後讓它消失。

同樣,我不希望它向用戶顯示任何內容。這是我的代碼。不工作..我錯過了什麼嗎?

unsigned int canvasFrameBuffer; 
bglGenFramebuffers(1, &canvasFrameBuffer); 
bglBindFramebuffer(BGL_RENDERBUFFER, canvasFrameBuffer); 
unsigned int canvasRenderBuffer; 
bglGenRenderbuffers(1, &canvasRenderBuffer); 
bglBindRenderbuffer(BGL_RENDERBUFFER, canvasRenderBuffer); 
bglRenderbufferStorage(BGL_RENDERBUFFER, BGL_RGBA4, width, height); 
bglFramebufferRenderbuffer(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_RENDERBUFFER, canvasRenderBuffer); 

unsigned int canvasTexture; 
bglGenTextures(1, &canvasTexture); 
bglBindTexture(BGL_TEXTURE_2D, canvasTexture); 
bglTexImage2D(BGL_TEXTURE_2D, 0, BGL_RGB, width, height, 0, BGL_RGB, BGL_UNSIGNED_BYTE, 0); 
bglFramebufferTexture2D(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_TEXTURE_2D, canvasTexture, 0); 

Matrix::matrix_t identity; 
Matrix::LoadIdentity(&identity); 
bglClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
bglClear(BGL_COLOR_BUFFER_BIT); 
Draw(&identity, &identity, this); 
bglFlush(); 
bglFinish(); 

byte *buffer = (byte*)Z_Malloc(width * height * 4, ZT_STATIC); 
bglReadPixels(0, 0, width, height, BGL_RGB, BGL_UNSIGNED_BYTE, buffer); 
SaveTGA("canvas.tga", buffer, width, height); 
Z_Free(buffer); 

// unbind frame buffer 
bglBindRenderbuffer(BGL_RENDERBUFFER, 0); 
bglBindFramebuffer(BGL_FRAMEBUFFER, 0); 
bglDeleteTextures(1, &canvasTexture); 
bglDeleteRenderbuffers(1, &canvasRenderBuffer); 
bglDeleteFramebuffers(1, &canvasFrameBuffer); 
+0

我發現渲染到的一些信息 - 紋理,但我不知道這是我想要的,因爲我想呈現給一個te陣列用於保存/分析圖像數據。我很好奇正確的道路是什麼。 – user1054922 2013-05-12 16:30:32

+1

緩衝區是否在屏幕上結束或者GPU仍然需要渲染。有沒有辦法讓屏幕外渲染不會影響性能... – 2013-05-12 16:35:20

+0

我不是說影響性能,我只是說沒有向用戶展示任何東西(即閃爍) – user1054922 2013-05-12 16:37:50

回答

4

這裏的解決方案,任何人誰需要它:

// Create framebuffer 
unsigned int canvasFrameBuffer; 
glGenFramebuffers(1, &canvasFrameBuffer); 
glBindFramebuffer(GL_RENDERBUFFER, canvasFrameBuffer); 

// Attach renderbuffer 
unsigned int canvasRenderBuffer; 
glGenRenderbuffers(1, &canvasRenderBuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, canvasRenderBuffer); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, width, height); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, canvasRenderBuffer); 

    // Clear the target (optional) 
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

    // Draw whatever you want here 

char *buffer = (char*)malloc(width * height * 3); 
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); 
SaveTGA("canvas.tga", buffer, width, height); // Your own function to save the image data to a file (in this case, a TGA) 
free(buffer); 

// unbind frame buffer 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glDeleteRenderbuffers(1, &canvasRenderBuffer); 
glDeleteFramebuffers(1, &canvasFrameBuffer); 
+0

你可以請建議如果寬度/高度大於GL_MAX_RENDERBUFFER_SIZE,你會怎麼做?所以不可能創建所需大小的渲染緩衝區...... – XZen 2015-01-19 12:18:23

+0

我無法在linux上運行它。什麼是BGL_RGBA4,ZT_CACHE和Z_MALLOC,SAVE_TGA,Z_FREE? – 2016-11-27 11:47:27

+0

對不起,這些是我建立的功能。我編輯了我的帖子,用標準等價物替換它們。 – user1054922 2016-11-29 14:40:07

1

您可以渲染到紋理,讀取像素並繪製具有該紋理的四邊形(如果要顯示給用戶)。它不應該閃爍,但它會明顯降低性能。

在iOS設備上,例如:

+0

我試圖渲染一個離屏紋理的一些代碼更新後。 – user1054922 2013-05-12 16:45:16

+0

在stackoverflow上用一些相關的問題用答案更新了我的答案。 – Trax 2013-05-12 16:45:53

+0

我沒有看到glBindFramebuffer的調用,它是否在Draw中? – Trax 2013-05-12 16:49:40