我正在开发记录 Unity 游戏屏幕的 Android 插件。为此,我使用了 OpenGL FBO。伪代码很简单,如下所示:
// Bind frame buffer as a render target
mFrameBuffer.bind();
// Render scene to frame buffer
renderScene();
// Restore rendering target, unbind FBO
mFrameBuffer.unbind();
// Draw texture into display
mTexture.draw(mFrameBuffer.getTexture());
// Make video surface a rendering target
videoCapture.captureFrame(mFrameBuffer.getTexture());
输出视频没问题,但我在使用从 FBO 获取的离屏纹理渲染到窗口显示时遇到了问题。我检查了我的代码,发现对 glDrawArray 的调用失败,错误代码为 GL_INVALID_OPERATION
。
我的渲染代码
public void draw(int textureId) {
this.shader.use();
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
Log.getPossibleGLError("active texture0");
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
Log.getPossibleGLError("bind texture when redraw");
int uOrientationM = this.shader.getAttributeLocation("uOrientationM");
Log.getPossibleGLError("get orientation matrix");
int uTransformM = this.shader.getAttributeLocation("uTransformM");
Log.getPossibleGLError("get transform matrix");
GLES20.glUniformMatrix4fv(uOrientationM, 1, false, this.orientationMatrix, 0);
Log.getPossibleGLError("set orientation matrix when redraw");
GLES20.glUniformMatrix4fv(uTransformM, 1, false, this.transformMatrix, 0);
Log.getPossibleGLError("set uniform matrix when redraw");
renderQuad(this.shader.getAttributeLocation("aPosition"));
Log.getPossibleGLError("render quad when redraw");
this.shader.unUse();
}
private void renderQuad(int aPosition) {
GLES20.glVertexAttribPointer(aPosition, 2, GLES20.GL_BYTE, false, 0, this.fullQuadVertices);
Log.getPossibleGLError("get vertex attrib pointer");
GLES20.glEnableVertexAttribArray(aPosition);
Log.getPossibleGLError("enable vertex array");
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
// error occurs after execute glDrawArrays
Log.getPossibleGLError("draw array ");
}
此代码在渲染到 videoSurface 时运行良好,但在渲染到窗口显示时失败。
我的问题有什么解决方案吗?
渲染以显示日志:发生 GL_INVALID_OPERATION 错误
glUseProgram(program = 31)
glActiveTexture(texture = GL_TEXTURE0)
glGetError(void) = (GLenum) GL_NO_ERROR
glBindTexture(target = GL_TEXTURE_2D, texture = 13)
glGetError(void) = (GLenum) GL_NO_ERROR
glGetError(void) = (GLenum) GL_NO_ERROR
glGetError(void) = (GLenum) GL_NO_ERROR
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [1.0, 0.0, 0.0, 0.0, -0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])
glGetError(void) = (GLenum) GL_NO_ERROR
glUniformMatrix4fv(location = 1, count = 1, transpose = false, value = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])
glGetError(void) = (GLenum) GL_NO_ERROR
glVertexAttribPointer(indx = 0, size = 2, type = GL_BYTE, normalized = false, stride = 0, ptr = 0x42b1ae38)
glGetError(void) = (GLenum) GL_NO_ERROR
glEnableVertexAttribArray(index = 0)
glGetError(void) = (GLenum) GL_NO_ERROR
glValidateProgram(program = 31)
glGetError(void) = (GLenum) GL_NO_ERROR
glGetProgramiv(program = 31, pname = GL_VALIDATE_STATUS, params = [1])
glGetProgramiv(program = 31, pname = GL_LINK_STATUS, params = [1])
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glGetError(void) = (GLenum) GL_INVALID_OPERATION
glGetError(void) = (GLenum) GL_NO_ERROR
渲染到视频日志:运行正常,没有错误
glUseProgram(program = 31)
glActiveTexture(texture = GL_TEXTURE0)
glGetError(void) = (GLenum) GL_NO_ERROR
glBindTexture(target = GL_TEXTURE_2D, texture = 13)
glGetError(void) = (GLenum) GL_NO_ERROR
glGetAttribLocation(program = 31, name = uOrientationM) = (GLint) -1
glGetError(void) = (GLenum) GL_NO_ERROR
glGetUniformLocation(program = 31, name = uOrientationM) = (GLint) 0
glGetError(void) = (GLenum) GL_NO_ERROR
glGetError(void) = (GLenum) GL_NO_ERROR
glGetAttribLocation(program = 31, name = uTransformM) = (GLint) -1
glGetError(void) = (GLenum) GL_NO_ERROR
glGetUniformLocation(program = 31, name = uTransformM) = (GLint) 1
glGetError(void) = (GLenum) GL_NO_ERROR
glGetError(void) = (GLenum) GL_NO_ERROR
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [1.0, 0.0, 0.0, 0.0, -0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])
glGetError(void) = (GLenum) GL_NO_ERROR
glUniformMatrix4fv(location = 1, count = 1, transpose = false, value = [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])
glGetError(void) = (GLenum) GL_NO_ERROR
glGetAttribLocation(program = 31, name = aPosition) = (GLint) 0
glGetError(void) = (GLenum) GL_NO_ERROR
glVertexAttribPointer(indx = 0, size = 2, type = GL_BYTE, normalized = false, stride = 0, ptr = 0x42b1ae38)
glGetError(void) = (GLenum) GL_NO_ERROR
glEnableVertexAttribArray(index = 0)
glGetError(void) = (GLenum) GL_NO_ERROR
glValidateProgram(program = 31)
glGetError(void) = (GLenum) GL_NO_ERROR
glGetProgramiv(program = 31, pname = GL_VALIDATE_STATUS, params = [1])
glGetProgramiv(program = 31, pname = GL_LINK_STATUS, params = [1])
glVertexAttribPointerData(indx = 0, size = 2, type = GL_BYTE, normalized = false, stride = 2, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glGetError(void) = (GLenum) GL_NO_ERROR
glGetError(void) = (GLenum) GL_NO_ERROR
glUseProgram(program = 0)
最佳答案
经过对 OpenGl 的多次调查,我终于解决了这个问题。问题是当我尝试将纹理重绘到屏幕时,数组缓冲区和元素数组缓冲区被错误地指向。解决方案非常简单,我创建了自己的数组缓冲区和元素数组缓冲区,然后在尝试重绘到屏幕之前绑定(bind)它们。它工作正常,没有错误 :D
关于android - 在 Android 中使用 FBO 录制屏幕,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25074021/