使用 OpengGLES2(角度)从帧缓冲区对象中读取
Reading from frame buffer object with OpengGLES2 (Angle)
使用 Angle 将 UWP 应用程序编程为 运行 OpenGL ES,我遇到了使用 glReadPixels
从帧缓冲区对象读取的基本操作的问题。
从 Visual Studio 模板 "OpenglES2 Application (Android,iOS,Windows Universal)" 开始,我可以将默认场景渲染检索到内存缓冲区中。
初始化:
void SimpleRenderer::InitFbo()
{
int buf_size = tex_height*tex_width * 4;
mReadBuf = new char[buf_size];
memset(mReadBuf, 123, buf_size); // arbitrary value to detect changes
}
绘图函数:
void SimpleRenderer::Draw()
{
// drawing calls here
// (...)
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);
// success : mReadBuf is updated with pixel values
}
但是如果我只是创建一个帧缓冲区对象,尝试在其中绘制并检索结果,glReadPixels
不会 return 任何值,并且 glError
returns INVALID_FRAMEBUFFER_OPERATION
.
初始化:
void SimpleRenderer::InitFbo()
{
glGenFramebuffers(1, &mRenderFbo);
glGenTextures(1, &mRenderTexture);
int buf_size = tex_height*tex_width * 4;
char*buf = new char[buf_size];
memset(buf, 255, buf_size);
glBindTexture(GL_TEXTURE_2D, mRenderTexture);
glTexImage2D(GL_TEXTURE_2D, 0, 4,
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mRenderTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
delete[] buf;
mReadBuf = new char[buf_size];
memset(mReadBuf, 123, buf_size);
}
绘图函数:
void SimpleRenderer::Draw()
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);
// drawing calls here
// (...)
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);
// failure : mReadBuf is unchanged
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
*edit - 由于下面的评论解决了。纹理的正确初始化是
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
郑重声明,在它得到解决之前,我正在使用 glCheckFramebufferStatus
检查帧缓冲区状态,returned GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
。
OpenGL函数的第三个参数glTexImage2D
指定纹理缓冲区的内部格式。
在方法 SimpleRenderer::InitFbo
中,您将 4
传递给内部格式,这不是有效参数。使用 GL_RGBA
代替:
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA, // <-----------------------
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
请注意,内部格式(在 OpenGL ES 2.0 中)的有效参数为 GL_ALPHA
、GL_LUMINANCE
、GL_LUMINANCE_ALPHA
、GL_RGB
、GL_RGBA
。
如果您在调用 glTexImage2D
之后使用 glGetError
,您将得到 GL_INVALID_VALUE
,如果内部格式不是可接受的格式,则会生成该代码。此外,如果纹理附加到帧缓冲区并且 glReadPixels
导致 INVALID_FRAMEBUFFER_OPERATION
错误,这会导致 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
错误(使用 glCheckFramebufferStatus
检查时)。
使用 Angle 将 UWP 应用程序编程为 运行 OpenGL ES,我遇到了使用 glReadPixels
从帧缓冲区对象读取的基本操作的问题。
从 Visual Studio 模板 "OpenglES2 Application (Android,iOS,Windows Universal)" 开始,我可以将默认场景渲染检索到内存缓冲区中。
初始化:
void SimpleRenderer::InitFbo()
{
int buf_size = tex_height*tex_width * 4;
mReadBuf = new char[buf_size];
memset(mReadBuf, 123, buf_size); // arbitrary value to detect changes
}
绘图函数:
void SimpleRenderer::Draw()
{
// drawing calls here
// (...)
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);
// success : mReadBuf is updated with pixel values
}
但是如果我只是创建一个帧缓冲区对象,尝试在其中绘制并检索结果,glReadPixels
不会 return 任何值,并且 glError
returns INVALID_FRAMEBUFFER_OPERATION
.
初始化:
void SimpleRenderer::InitFbo()
{
glGenFramebuffers(1, &mRenderFbo);
glGenTextures(1, &mRenderTexture);
int buf_size = tex_height*tex_width * 4;
char*buf = new char[buf_size];
memset(buf, 255, buf_size);
glBindTexture(GL_TEXTURE_2D, mRenderTexture);
glTexImage2D(GL_TEXTURE_2D, 0, 4,
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mRenderTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
delete[] buf;
mReadBuf = new char[buf_size];
memset(mReadBuf, 123, buf_size);
}
绘图函数:
void SimpleRenderer::Draw()
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderFbo);
// drawing calls here
// (...)
glReadPixels(0, 0, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, mReadBuf);
// failure : mReadBuf is unchanged
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
*edit - 由于下面的评论解决了。纹理的正确初始化是
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
郑重声明,在它得到解决之前,我正在使用 glCheckFramebufferStatus
检查帧缓冲区状态,returned GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
。
OpenGL函数的第三个参数glTexImage2D
指定纹理缓冲区的内部格式。
在方法 SimpleRenderer::InitFbo
中,您将 4
传递给内部格式,这不是有效参数。使用 GL_RGBA
代替:
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA, // <-----------------------
tex_width,
tex_height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
buf);
请注意,内部格式(在 OpenGL ES 2.0 中)的有效参数为 GL_ALPHA
、GL_LUMINANCE
、GL_LUMINANCE_ALPHA
、GL_RGB
、GL_RGBA
。
如果您在调用 glTexImage2D
之后使用 glGetError
,您将得到 GL_INVALID_VALUE
,如果内部格式不是可接受的格式,则会生成该代码。此外,如果纹理附加到帧缓冲区并且 glReadPixels
导致 INVALID_FRAMEBUFFER_OPERATION
错误,这会导致 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
错误(使用 glCheckFramebufferStatus
检查时)。