OpenGL ES渲染到纹理,然后绘制纹理

发布于 2024-08-09 15:23:50 字数 2402 浏览 4 评论 0原文

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

实例变量:

GLuint textureFrameBuffer;
Texture2D * texture;

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

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);

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

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

但是,如果我渲染到“textureFrameBuffer”,则绘制“texture”在屏幕上,生成的图像是上下颠倒且“内向外”的。也就是说,看起来 3d 对象的法线似乎指向内而不是向外 - 每个对象的最前面都是透明的,我可以看到背面的内部。代码如下:

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方法中)来轻松地将图像正面朝上翻转,但这并不能解决“由内而外”的问题。

我尝试用手动创建的OpenGL纹理替换Texture2D纹理,结果是一样的。绘制从 PNG 图像加载的 Texture2D 效果很好。

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

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

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

关于如何解决这个问题有什么建议吗?谢谢!

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.

Instance variables:

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];

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];

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.

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.

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);

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三五鸿雁 2024-08-16 15:23:50

有趣的是,当直接绘制到后台缓冲区时,您会看到不同的结果。由于您使用的是 iPhone 平台,因此您总是绘制到 FBO,即使您绘制到后台缓冲区也是如此。

确保您的屏幕外 FBO 连接了深度缓冲区。在初始化代码中,您可能需要在 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);

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.

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文