OpenGL ES渲染到纹理,然后绘制纹理 [英] OpenGL ES render to texture, then draw texture

查看:437
本文介绍了OpenGL ES渲染到纹理,然后绘制纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试渲染到纹理,然后使用iPhone上的OpenGL ES将该纹理绘制到屏幕上。我正在使用这个问题作为起点,并在子类中进行绘图Apple的演示版EAGLView。

I'm trying to render to a texture, then draw that texture to the screen using OpenGL ES on the iPhone. I'm using this question as a starting point, and doing the drawing in a subclass of Apple's demo EAGLView.

实例变量:

GLuint textureFrameBuffer;
Texture2D * texture;

要初始化帧缓冲区和纹理,我这样做:

To initialize the frame buffer and texture, I'm doing this:

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

// initWithData results in a white image on the device (works fine in the simulator)
texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"blank320.png"]];

// create framebuffer
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

// attach renderbuffer
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0);

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    NSLog(@"incomplete");

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

现在,如果我像往常一样将我的场景画到屏幕上,它可以正常工作:

Now, if I simply draw my scene to the screen as usual, it works fine:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw some triangles, complete with vertex normals
[contentDelegate draw];
[self swapBuffers];

但是,如果我渲染到'textureFrameBuffer',那么将'texture'绘制到屏幕上,结果图像是颠倒的,从里到外。也就是说,看起来三维物体的法线指向内部而不是外部 - 每个物体的最前面是透明的,我可以看到背面的内部。这是代码:

But, if I render to 'textureFrameBuffer', then draw 'texture' to the screen, the resulting image is upside down and "inside out". That is, it looks as though the normals of the 3d objects are pointing inward rather than outward -- the frontmost face of each object is transparent, and I can see the inside of the back face. Here's the code:

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// draw some polygons
[contentDelegate draw];

glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
glColor4f(1, 1, 1, 1);
[texture drawInRect:CGRectMake(0, 0, 320, 480)];    
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);

[self swapBuffers];

我可以通过相应地重新排序(glTexCoordPointer)坐标来轻松地将图像正面翻转(在Texture2D中drawInRect方法),但这并没有解决由内而外的问题。

I can flip the image rightside-up easily enough by reordering the (glTexCoordPointer) coordinates accordingly (in Texture2D's drawInRect method), but that doesn't solve the "inside-out" issue.

我尝试用手动创建的OpenGL纹理替换Texture2D纹理,结果是相同。绘制从PNG图像加载的Texture2D工作正常。

I tried replacing the Texture2D texture with a manually created OpenGL texture, and the result was the same. Drawing a Texture2D loaded from a PNG image works fine.

至于绘制对象,每个顶点都指定了一个单位法线,并且 GL_NORMALIZE 已启用。

As for drawing the objects, each vertex has a unit normal specified, and GL_NORMALIZE is enabled.

glVertexPointer(3, GL_FLOAT, 0, myVerts);
glNormalPointer(GL_FLOAT, 0, myNormals);
glDrawArrays(GL_TRIANGLES, 0, numVerts);

当渲染到屏幕时,一切都很好; GL_DEPTH_TEST 已启用并且运行良好。

Everything draws fine when it's rendered to the screen; GL_DEPTH_TEST is enabled and is working great.

有关如何解决此问题的任何建议?谢谢!

Any suggestions as to how to fix this? Thanks!

推荐答案

这个有趣的部分是,当你直接绘制到后备缓冲区时,你会看到不同的结果。由于您使用的是iPhone平台,即使您正在使用后备缓冲区,也总是总是绘制到FBO。

The interesting part of this is that you're seeing a different result when drawing directly to the backbuffer. Since you're on the iPhone platform, you're always drawing to an FBO, even when you're drawing to the backbuffer.

确保您的屏幕外FBO附加了深度缓冲区。在初始化代码中,您可能希望在 glBindFramebufferOES(...)之后添加以下代码段。

Make sure that you have a depth buffer attached to your offscreen FBO. In your initialization code, you might want to add the following snippet right after the glBindFramebufferOES(...).

// attach depth buffer
GLuint depthRenderbuffer;
glGenRenderbuffersOES(1, &depthRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);

这篇关于OpenGL ES渲染到纹理,然后绘制纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆