OpenGL ES iPhone,使用 glClearColor 时图像损坏

Posted

技术标签:

【中文标题】OpenGL ES iPhone,使用 glClearColor 时图像损坏【英文标题】:OpenGL ES iPhone, corrupt image when using glClearColor 【发布时间】:2012-02-24 11:10:32 【问题描述】:

我刚刚开始了解 iPhone 上的 OpenGL ES。我试图获得一个非常简单的示例,它设置一个 EAGLContext 和渲染缓冲区,然后简单地使用 glClearColor 来设置屏幕颜色。

我的代码编译并执行,但不幸的是,我看到的不是预期的灰屏,而是带有随机损坏模式的白色图像。我猜我没有正确设置,我希望我的错误对于在这方面有一点经验的人来说是显而易见的。

我的代码是:

AppDelegate.h

#import "GLView.h"
#import <UIKit/UIKit.h>

@interface AppDelegate : NSObject <UIApplicationDelegate> 
@private
  UIWindow* m_window;
  GLView* m_view;


@end

AppDelegate.m

#import "AppDelegate.h"
#import "AppDelegate.h"
#import "GLView.h"

@implementation AppDelegate

- (void) applicationDidFinishLaunching: (UIApplication*) application

  CGRect screenBounds = [[UIScreen mainScreen] bounds];

  m_window = [[UIWindow alloc] initWithFrame: screenBounds];
  m_view = [[GLView alloc] initWithFrame: screenBounds];

  [m_window addSubview: m_view];
  [m_window makeKeyAndVisible];


- (void) dealloc

  [m_view release];
  [m_window release];
  [super dealloc];


@end

GLView.h

#import <QuartzCore/QuartzCore.h>

@interface GLView : UIView 
@private
  EAGLContext* m_context;



- (void) drawView;

@end

GLView.mm

#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#import "GLView.h"

@implementation GLView

+ (Class) layerClass

  return [CAEAGLLayer class];


- (id)initWithFrame:(CGRect)frame

    self = [super initWithFrame:frame];
    if (self) 

      //Set up the layer and context
      CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer;
      eaglLayer.opaque = YES;

      m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

      if (!m_context || ![EAGLContext setCurrentContext:m_context]) 
        [self release];
        return nil;
      

      // Create & bind the color buffer so that the caller can allocate its space.
      GLuint renderbuffer;
      glGenRenderbuffersOES(1, &renderbuffer);
      glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer);
      [m_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer];
      glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));

      [self drawView];

    
    return self;


- (void)drawView

  glClearColor(0.5f,0.5f,0.5f,1.0f);
  glClear(GL_COLOR_BUFFER_BIT);
  [m_context presentRenderbuffer:GL_RENDERBUFFER_OES];


- (void) dealloc

  if([EAGLContext currentContext] == m_context)
    [EAGLContext setCurrentContext:nil];
  [m_context release];
  [super dealloc];

非常感谢您的帮助。

【问题讨论】:

【参考方案1】:

无论哪种方式,我都找不到明确说明它的文档,但我认为您可能只需要明确地创建一个帧缓冲区。在 GL 中,渲染缓冲区是可以写入传出片段的某些组件的任何东西——所以像您创建的颜色缓冲区或深度缓冲区或模板缓冲区或其他类似的东西。帧缓冲区是构成绘图目标的渲染缓冲区的集合。

所以这都是相当微不足道的东西,但是您要添加的是对glGenFramebuffersOES 的调用,然后在glBindRenderbufferOES 之前调用glBindFramebufferOES(因为它将渲染缓冲区绑定到帧缓冲区的上下文中)。如果您曾经添加渲染到纹理或决定使用 Apple 的多重采样扩展,那么您将绑定和取消绑定的是帧缓冲区,而不是渲染缓冲区。

为了验证正确性,您还应该在绑定并创建所需的渲染缓冲区后调用glCheckFramebufferStatusOES — 就像这样:

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)

    // some sort of error path here

如果您仍然得到无意义的像素输出,这将有助于消除一个调查领域。

【讨论】:

【参考方案2】:

你忘了在

后面加上一行
[m_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer];
////
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, renderbuffer);
////

还有条件

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)

永远是真的!!!尽管我得到了想要的输出。

【讨论】:

以上是关于OpenGL ES iPhone,使用 glClearColor 时图像损坏的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:Quartz2d 与 OpenGL ES

使用“2x”按钮时,iPhone OpenGL ES 应用程序在 iPad 上被杀死

在 iPhone 上使用 CADisplayLink 在 OpenGL ES 视图中进行等速旋转

iPhone 成本与收益 - OpenGL ES 1.x 与 2.0

iPhone Cheetah 3D OpenGL ES 顶点缓冲对象 (VBO) 示例

iPhone 应用程序中奇怪的 OpenGL ES 行为