将OpenGL ES 2.0渲染为图像
我正在尝试对图像文件进行一些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);
这里的解决方案,任何人谁需要它:
// 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);
你可以请建议如果宽度/高度大于GL_MAX_RENDERBUFFER_SIZE,你会怎么做?所以不可能创建所需大小的渲染缓冲区...... – XZen 2015-01-19 12:18:23
我无法在linux上运行它。什么是BGL_RGBA4,ZT_CACHE和Z_MALLOC,SAVE_TGA,Z_FREE? – 2016-11-27 11:47:27
对不起,这些是我建立的功能。我编辑了我的帖子,用标准等价物替换它们。 – user1054922 2016-11-29 14:40:07
您可以渲染到纹理,读取像素并绘制具有该纹理的四边形(如果要显示给用户)。它不应该闪烁,但它会明显降低性能。
在iOS设备上,例如:
我试图渲染一个离屏纹理的一些代码更新后。 – user1054922 2013-05-12 16:45:16
在stackoverflow上用一些相关的问题用答案更新了我的答案。 – Trax 2013-05-12 16:45:53
我没有看到glBindFramebuffer的调用,它是否在Draw中? – Trax 2013-05-12 16:49:40
我发现渲染到的一些信息 - 纹理,但我不知道这是我想要的,因为我想呈现给一个te阵列用于保存/分析图像数据。我很好奇正确的道路是什么。 – user1054922 2013-05-12 16:30:32
缓冲区是否在屏幕上结束或者GPU仍然需要渲染。有没有办法让屏幕外渲染不会影响性能... – 2013-05-12 16:35:20
我不是说影响性能,我只是说没有向用户展示任何东西(即闪烁) – user1054922 2013-05-12 16:37:50