OpenGL ES FBO缩放

这个问题跟随Matic Oblak推荐的原始问题

一旦FBO被设置并渲染,渲染后的图像如何提供回默认渲染缓冲区并以缩放版本显示。

-(void)setupFBO { glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); } 

首先呈现给FBO:

 -(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ glBindFramebuffer(GL_FRAMEBUFFER, fbo); glViewport (0, 0, 160, 144); glClearColor (1.0f, 0.0f, 0.0f, 0.5f); glClear (GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glViewport(0, 0, 160, 144); glBindVertexArrayOES(_vertexArray); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

如果我取消注释的FBO绑定,正方形显示正确 – 所以我不认为它与VBO和VAO的问题。

尝试将结果显示回缩放到适合屏幕的主视图:

 [((GLKView *) self.view) bindDrawable]; glViewport (0, 0, view.frame.size.width, view.frame.size.height); glClearColor (0.0f, 1.0f, 0.0f, 0.5f); glClear (GL_COLOR_BUFFER_BIT); //vb2 has the scaled vertex coordinates glBindBuffer(GL_ARRAY_BUFFER, vb2); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, 0); //make sure we are not redrawing the same thing? the texture should be //a colored cube based on what the fbo rendered. glDisableVertexAttribArray(GLKVertexAttribColor); //create a buffer for the texture coordinates //should be moved in setup phase, but left in for testing glGenBuffers(1, &texBuffer); glBindBuffer(GL_ARRAY_BUFFER, texBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*8, squareTex, GL_STATIC_DRAW); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, 0); //bind to the fbo texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, tex); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

我已阅读并遵循的一些教程。

  1. OpenGL的FBO例子
  2. Songho OGL FBO
  3. RTT

最终,我希望在模拟器的整个宽度(保持高度比例)中显示(160×144像素)的仿真GB屏幕。

我从一个小广场开始,试图伸展出来,以实现复古平方像素效果。

要达到拉伸效果,所有您需要做的就是绘制具有纹理的全屏矩形。 如果不使用matrix,则只需要在[-1,1]范围内设置顶点位置数据,以便对于三angular形条带:

 {-1, -1, 1, -1, -1, 1, 1, 1} 

纹理坐标应该取决于原始纹理视口与纹理大小的比例。 对于你的160x144的例子,最接近纹理尺寸足够大的数据将是256x256 ,结果是ratio = (160/256, 144/256)所以坐标是

 {.0, .0, ratio.x, .0, .0, ratio.y, ratio.x, ratio.y} 

如果这不显示结果,您将需要find可能在任何时候的问题。 首先,我将首先尝试使用纯色绘制该坐标,以查看矩形是否全屏显示。 如果是的话,这个问题很可能是从FBO收到的贴图。 如果我认为你正在使用Xcode,最好的工具是创build一个帧快照(一个在左下angular的工具),它将显示所有的调用和帧的任何点的所有纹理。 有了它,你可以看到纹理是否正确绘制。

不要忘了查看openGL错误( glGetError )并在附件glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE后检查FBO缓冲区的状态。

这是从我的一个项目创build一个FBO的方法。 这可能对你有一些用处。

  glGenFramebuffers(1, &_frameBuffer); glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); glGenRenderbuffers(1, &_renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, texture.textureWidth, texture.textureHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _renderBuffer); [texture bind]; glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.textureID, 0); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_bufferWidth); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_bufferHeight); [GLGlobalTools checkFramebufferStatus]; [GLGlobalTools checkError]; _bufferWidthf = _bufferWidth; _bufferHeightf = _bufferHeight; _surfaceWidth = (GLint)texture.imageWidth; _surfaceHeight = (GLint)texture.imageHeight;