我一直致力于从OpenGL获取屏幕截图,然后在屏幕上呈现相同的屏幕截图。为此,我创建了两个帧缓冲区。 1用于渲染(ratinaFramebuffer)和1用于使用apple纹理缓存绘图(textureFramebuffer)。使用以下代码创建两者(变量名称除外)。
glGenFramebuffers(1, &ratinaFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, ratinaFramebuffer);
glGenRenderbuffers(1, &ratinaColorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, ratinaColorRenderbuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
glGenRenderbuffers(1, &ratinaDepthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, ratinaDepthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ratinaDepthRenderbuffer);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ;
if(status != GL_FRAMEBUFFER_COMPLETE)
{
NSLog(@"failed to make complete framebuffer object %x", status);
}
这是我的渲染代码的样子
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Clear content
glBindFramebuffer(GL_FRAMEBUFFER, ratinaFramebuffer);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, textureFramebuffer);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Start drawing
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
static int nColor = 104;
glClearColor(0, (++nColor & 0xff)/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _floorTexture);
glUniform1i(_textureUniform, 0);
// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer2);
glActiveTexture(GL_TEXTURE0); // unneccc in practice
glBindTexture(GL_TEXTURE_2D, _fishTexture);
glUniform1i(_textureUniform, 0); // unnecc in practice
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
glDrawElements(GL_TRIANGLE_STRIP, sizeof(Indices2)/sizeof(Indices2[0]), GL_UNSIGNED_BYTE, 0);
// Get the image
CGImageRef cgImage = NULL;
UIImage *screenImageimage = nil;
OSStatus res = CreateCGImageFromCVPixelBuffer(renderTarget,&cgImage);
if (res == noErr)
{
screenImageimage = [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationUp];
}
此时,图像被完美地绘制到纹理中。但是当我尝试在屏幕上渲染它时,相同的纹理,它不会被绘制:(。它显示了我用清晰的颜色给出的蓝色,但没有别的。
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ratinaFramebuffer);
glBindTexture(GL_TEXTURE_2D, 0);
glClearColor(0, 255/255.0, 255/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, renderTexture);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, ratinaColorRenderbuffer);
[_context presentRenderbuffer:GL_RENDERBUFFER_OES];
答案 0 :(得分:1)
当你绘制到单独的帧缓冲区时,你可以附加一个纹理,最后你可以有效地绘制到纹理本身。完成此绘图后,您可以像使用任何其他绘图一样使用纹理,包括将其绘制到主屏幕缓冲区。
这样做时应该检查几点:
很难说你现在缺少什么,但目前最好的镜头是检查视口。除此之外,如果您只是绘制全屏纹理,则无需使用主缓冲区复杂化。您可以禁用矩阵,只需使用默认的[-1,1]坐标系。
答案 1 :(得分:0)
问题解决了,因为我是openGL的新手并且我没有绘制屏幕帧缓冲,我通过在屏幕调用的渲染中使用下面的代码来完成。如果有人需要在初级阶段查看,那就发布了
GLfloat coordinates[] = { 0, 1,
1, 1,
0, 0,
1, 0 };
GLfloat width = self.frame.size.width,
height = self.frame.size.height;
GLfloat vertices[] = { -width / 2 + point.x, -height / 2 + point.y, 0.0,
width / 2 + point.x, -height / 2 + point.y, 0.0,
-width / 2 + point.x, height / 2 + point.y, 0.0,
width / 2 + point.x, height / 2 + point.y, 0.0 };
glBindTexture(GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
虽然,这显示了纹理但是在另一个帧缓冲区中绘制的小盒子中。虽然顶点和坐标是完整的屏幕,但它不会绘制到完整的屏幕。如果我找到了,就会编辑这个。