为什么我没有在这个程序中获得灰色背景

时间:2010-11-12 04:50:08

标签: objective-c cocoa-touch opengl-es quartz-graphics

我按照此页面上的教程进行操作:

http://iphone-3d-programming.labs.oreilly.com/ch01.html

我深入到它所说的部分,“编译和构建,你现在应该看到一个坚实的灰色屏幕.Hurray!”但是,当我运行该程序时,我只是得到一个黑屏。

这些是文件的样子:

HelloArrowAppDelegate.h

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

@interface HelloArrowAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *m_window;
    GLView* m_view;
}

@end

HelloArrowAppDelegate.mm

#import "HelloArrowAppDelegate.h"

@implementation HelloArrowAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.
    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];

    return YES;
}

- (void)dealloc {
    [m_view release];
    [m_window release];
    [super dealloc];
}

@end

GLView.h

#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>

@interface GLView : UIView {
    EAGLContext* m_context;
}

-(void) drawView;

@end

GLView.mm

#import "GLView.h"

@implementation GLView

- (void) drawView
{
    glClearColor(0.5f, 0.5f, 0.5f, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    [m_context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        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;
        }

        // OpenGL Initialization
        GLuint framebuffer, renderbuffer;
        glGenFramebuffersOES(1, &framebuffer);
        glGenFramebuffersOES(1, &renderbuffer);

        [m_context
         renderbufferStorage:GL_RENDERBUFFER_OES
         fromDrawable: eaglLayer];

        glFramebufferRenderbufferOES(
                                     GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                                     GL_RENDERBUFFER_OES, renderbuffer);

        glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));

        [self drawView];
    }
    return self;
}

- (void)dealloc {
    if ([EAGLContext currentContext] == m_context) {
        [EAGLContext setCurrentContext:nil];
    }

    [m_context release];
    [super dealloc];
}

@end

6 个答案:

答案 0 :(得分:2)

initWithFrame不正确。您想要生成帧缓冲区和渲染缓冲区并链接这两个缓冲区。而是生成两个帧缓冲区并完全忽略一个。您还应该在类中保留对它们的引用(变量'renderbuffer'和'framebuffer'),因为除非您想要泄漏内存,否则以后需要删除它们。

如果不解决第二个问题,我建议:

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        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;
        }

        // these should be in the class so that we can release them later,
        // this will leak resources
        GLuint framebuffer, renderbuffer;

        // generate and bind a framebuffer
        glGenFramebuffersOES(1, &framebuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

        // generate a colour renderbuffer; this example doesn't seem to want
        // e.g. a depth buffer, but if it did then you'd generate and add one
        // of those here also

        // generate and bind
        glGenRenderbuffersOES(1, &renderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, renderbuffer);

        // get storage from the layer
        [m_context
         renderbufferStorage:GL_RENDERBUFFER_OES
         fromDrawable: eaglLayer];

        // link to the framebuffer
        glFramebufferRenderbufferOES(
                                     GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
                                     GL_RENDERBUFFER_OES, renderbuffer);

        glViewport(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame));

        [self drawView];
    }
    return self;
}

将framebuffer和renderbuffer放在某个地方,你可以在相关时刻再次找到它们,你还应该:

- (void)dealloc {

    if(renderbuffer) glDeleteRenderbuffersOES(1, &renderbuffer);
    if(framebuffer) glDeleteFramebuffersOES(1, &framebuffer);

    if ([EAGLContext currentContext] == m_context) {
        [EAGLContext setCurrentContext:nil];
    }

    [m_context release];
    [super dealloc];
}

我已根据您提供的代码对此进行了测试。我得到了灰色的屏幕。将调用更改为glClearColor会更改屏幕的颜色,因此GL上下文显然正常工作。

答案 1 :(得分:1)

我遇到了这个问题并通过确保在@implementation行之后实现图层类来修复它。

@implementation GLView

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

答案 2 :(得分:1)

我通过删除线

获得了灰色背景
    m_window = [[UIWindow alloc] initWithFrame: screenBounds];
应用程序中的

:文件Hello Arrow AppDelegate.h中的didFinishLaunchingWithOptions:方法

答案 3 :(得分:0)

没有任何代码,可能很难告诉你大声笑

你的灰色窗口来自

(void) drawView
{
    glClearColor(0.5f, 0.5f, 0.5f, 1);
    glClear(GL_COLOR_BUFFER_BIT);

    [m_context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

检查是否正确调用

答案 4 :(得分:0)

最可能的原因是您在遵循教程时错过了一些内容。或者他们弄错了。无论哪个最有可能: - )

所以下一步是调试并弄清楚出了什么问题。很可能你错过了一行代码,这些代码会向显示器添加内容。我先查看代码的那一部分,然后将它与教程进行比较。

如果这不起作用,那么我会把你的代码副本作为备份,然后开始从中删除东西,直到你拥有绝对最少量的代码。然后发布在这里。没有一些代码,我们无法告诉你什么是错的。

答案 5 :(得分:0)

我尝试在上面的代码中添加以下内容:

- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
      CAEAGLLayer* eaglLayer = (CAEAGLLayer*) super.layer; 
      eaglLayer.opaque = YES;
      eaglLayer.drawableProperties = 
        [NSDictionary dictionaryWithObjectsAndKeys:
          [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, 
          kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];


...
}

在代码中我使用我定义了一个drawableProperties,但你似乎错过了它。