我是OpenGL ES的新手。我正在尝试为iOS应用程序的屏幕录制编写代码,尤其是游戏。
我使用'渲染纹理'使用此答案中的代码(https://stackoverflow.com/a/9704392/707773)描述的方法捕获屏幕并为cocos2d游戏编写视频。我做的一项修改是,当我致电int page = 1;
int size = 10
var customers = tx.Customers
.Where(x => x.....)
.Skip((page - 1) * 10).Take(size)
.ToList();
时,我使用CVOpenGLESTextureCacheCreate
代替[EAGLContext currentContext]
它会录制视频,但有两个问题
开始录制时,屏幕上的新绘图停止。我希望应用程序继续在屏幕上绘图。由于我是OpenGL ES的新手,我对帧缓冲对象等没有深刻理解,因此我很难弄清楚如何同时在屏幕上绘图并捕获屏幕。我会很感激这方面的代码示例。
录制的视频翻转过来。我怎样才能正确指明它?
之前我也考虑过[[GPUImageOpenGLESContext sharedImageProcessingOpenGLESContext] context]
方法,但这有性能上的缺点。
更新:还想到了一些想法。根据我的理解,
我可以简单地将纹理绘制回屏幕,但不知道如何。
更新: 主要吸引力
glReadPixels
将视频纹理缓冲区添加到帧
// ----- Display the keyframe -----
Texture* t = augmentationTexture[OBJECT_KEYFRAME_1 + playerIndex];
frameTextureID = [t textureID];
aspectRatio = (float)[t height] / (float)[t width];
texCoords = quadTexCoords;
// Get the current projection matrix
QCAR::Matrix44F projMatrix = vapp.projectionMatrix;
// If the current status is valid (not NOT_READY or ERROR), render the
// video quad with the texture we've just selected
if (NOT_READY != currentStatus) {
// Convert trackable pose to matrix for use with OpenGL
QCAR::Matrix44F modelViewMatrixVideo = QCAR::Tool::convertPose2GLMatrix(trackablePose);
QCAR::Matrix44F modelViewProjectionVideo;
// SampleApplicationUtils::translatePoseMatrix(0.0f, 0.0f, videoData[playerIndex].targetPositiveDimensions.data[0], &modelViewMatrixVideo.data[0]);
SampleApplicationUtils :: scalePoseMatrix(videoData[playerIndex].targetPositiveDimensions.data[0], videoData[playerIndex].targetPositiveDimensions.data[0] * aspectRatio, videoData[playerIndex].targetPositiveDimensions.data[0], &modelViewMatrixVideo.data[0]);
SampleApplicationUtils::multiplyMatrix(projMatrix.data, &modelViewMatrixVideo.data[0], &modelViewProjectionVideo.data[0]);
glUseProgram(shaderProgramID);
glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, quadVertices);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, quadNormals);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glEnableVertexAttribArray(vertexHandle);
glEnableVertexAttribArray(normalHandle);
glEnableVertexAttribArray(textureCoordHandle);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, frameTextureID);
glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (GLfloat*) &modelViewProjectionVideo.data[0]);
glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/);
glDrawElements(GL_TRIANGLES, kNumQuadIndices, GL_UNSIGNED_SHORT, quadIndices);
glDisableVertexAttribArray(vertexHandle);
glDisableVertexAttribArray(normalHandle);
glDisableVertexAttribArray(textureCoordHandle);
glUseProgram(0);
}
答案 0 :(得分:2)
您似乎缺少一些关于这些事情如何运作的知识,并且无法知道您的问题所在。让我为你分解一些事情,以便你可以找出你的问题,希望自己修复它,但另外问一些代码更具体的代码,显示什么是有效的,什么不是。
因此,从帧缓冲区开始,此对象是其他缓冲区的容器,在您的情况下可能是纹理和渲染缓冲区。通过绑定特定的帧缓冲区,您将告诉GPU绘制到连接到此帧缓冲区的缓冲区。最常见的附件是颜色,深度和模板缓冲区。最常见的是,创建新帧缓冲区的过程如下所示:
glRenderbufferStorage
或glTexImage2D
或在iOS中设置缓冲区的数据和格式,如果要将其绑定到renderbufferStorage:fromDrawable:
上的EAGLContext
宾语。 (最后一个可能由某些更高级别的对象完成,例如GLKView
)glFramebufferRenderbuffer
或glFramebufferTexture2D
这样您可以创建任意数量的帧缓冲区。要选择要绘制到哪个缓冲区,只需要绑定正确的帧缓冲区。
通常我们将帧缓冲区分为主帧缓冲区和帧缓冲区对象(FBO)。主框架缓冲区是代表您的屏幕并且ID为0的框架缓冲区,因此在大多数平台中,您可以简单地绑定0索引缓冲区以继续绘制到主屏幕/视图。但是在iOS上,这是非常重要的,从您的角度来看,没有主框架缓冲区这样的东西。您需要保存通过renderbufferStorage:fromDrawable:
生成的渲染缓冲区的ID,如果这不在您的代码中(您使用的是更高级别的工具),则需要通过调用<向GPU询问缓冲区ID / p>
GLint defaultFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &defaultFBO);
(找到here) 但是你需要确保在绑定主缓冲区时调用它,所以最好在开始录制之前,因此你知道它是正确的缓冲区。
然后FBO是任何其他不是主要的帧缓冲区。它也被称为屏幕外帧缓冲区。这些通常用于后处理或预处理。在您的情况下,您可以使用一个将像素绘制到纹理数据中,CPU可以使用您提供的链接中描述的纹理缓存轻松访问这些数据。所以现在你有至少2个缓冲区,主缓冲区和屏幕外缓冲区。屏幕外缓冲区将具有纹理,然后可以将其重新绘制到主缓冲区。现在你的绘制基本管道应该是这样的:
还有其他方法,例如
这将绘制场景两次,而不是重复使用FBO中纹理的相同场景。如果你没有在绘图上做任何繁重的操作,这些操作基本相同,但最好还是使用第一个。