Почему я не получаю серый фон в этой программе - PullRequest
0 голосов
/ 12 ноября 2010

Я следовал инструкциям на этой странице:

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

Я перешел к той части, где написано: "Скомпилируйте и соберите, и вы должны увидеть сплошной серый экран. Ура!" Однако когда я запускаю программу, у меня просто появляется черный экран.

Вот как выглядят файлы:

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 ]

2 голосов
/ 15 ноября 2010

Неверный 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 голос
/ 26 апреля 2011

Я получил серый фон, избавившись от строки

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

в приложении: didFinishLaunchingWithOptions: метод в файле HelloArrowAppDelegate.h

1 голос
/ 25 апреля 2011

Я столкнулся с этой проблемой и исправил ее в моем случае, убедившись, что класс слоя был реализован сразу после строки @implementation.

@implementation GLView

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}
0 голосов
/ 15 ноября 2010

Я бы попробовал добавить следующее к вашему коду:

- (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, но вы, похоже, его упускаете.

0 голосов
/ 12 ноября 2010

Наиболее вероятной причиной является то, что вы что-то пропустили, следуя инструкциям.Или они ошиблись.Что наиболее вероятно: -)

Итак, следующий этап - отладка и выяснение того, что пошло не так.Скорее всего, вы пропустили строку кода, которая добавляет материал на дисплей.Сначала я посмотрю в этом разделе вашего кода и сравню его с руководством.

Если это не сработает, тогда я возьму копию вашего кода в качестве резервной копии, затем начну извлекать из нее все, пока у вас не будет абсолютно минимального количества кода.Тогда опубликуйте это здесь.Без некоторого кода мы не можем сказать вам, что не так.

0 голосов
/ 12 ноября 2010

без какого-либо кода, вам может быть трудно сказать LOL

ваше серое окно исходит от

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

    [m_context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

проверьте, что это называется correclty

...