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

时间:2012-02-24 11:10:32

标签: iphone opengl-es

我刚刚开始在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];
}

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我无法找到明确说明的文档,但我认为你可能只需要明确地创建一个帧缓冲区。在GL中,渲染缓冲区是可以将输出片段的某些组件写入的任何内容 - 因此像您创建的颜色缓冲区或深度缓冲区或模板缓冲区或其他类似的颜色缓冲区。帧缓冲区是构成绘图目标的渲染缓冲区的集合。

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

作为对正确性的验证,您还应该在绑定并创建所需的渲染缓冲区后调用glCheckFramebufferStatusOES - 只需快速执行:

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
{
    // some sort of error path here
}

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

答案 1 :(得分:0)

您忘了在

之后添加一行
[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)

永远是真的!尽管我很想得到它。