Шаблон Xcode 4 OpenGL ES 1.1 - PullRequest
       5

Шаблон Xcode 4 OpenGL ES 1.1

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

Я запускаю новый проект opengles из xcode 4 и удаляю все ссылки и вызовы ES2 (я хочу использовать код рисования ES1).Мой пример проекта отлично работает на iphone 4, но не работает на iphone 3g и ipod 2-го поколения.Вот мой модифицированный код:

EAGLView.m

#import <QuartzCore/QuartzCore.h>

#import "EAGLView.h"

@interface EAGLView (PrivateMethods)
- (void)createFramebuffer;
- (void)deleteFramebuffer;
@end

@implementation EAGLView

@synthesize context;

// You must implement this method
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:.
- (id)initWithCoder:(NSCoder*)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

        eaglLayer.opaque = TRUE;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                                        kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                        nil];
    }

    return self;
}

- (void)dealloc
{
    [self deleteFramebuffer];    
    [context release];

    [super dealloc];
}

- (void)setContext:(EAGLContext *)newContext
{
    if (context != newContext) {
        [self deleteFramebuffer];

        [context release];
        context = [newContext retain];

        [EAGLContext setCurrentContext:nil];
    }
}

- (void)createFramebuffer
{
    if (context && !defaultFramebuffer) {
        [EAGLContext setCurrentContext:context];

        // Create default framebuffer object.
        glGenFramebuffersOES(1, &defaultFramebuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

        // Create color render buffer and allocate backing store.
        glGenRenderbuffersOES(1, &colorRenderbuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer];
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &framebufferWidth);
        glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &framebufferHeight);

        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

        if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
            NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    }
}

- (void)deleteFramebuffer
{
    if (context) {
        [EAGLContext setCurrentContext:context];

        if (defaultFramebuffer) {
            glDeleteFramebuffersOES(1, &defaultFramebuffer);
            defaultFramebuffer = 0;
        }

        if (colorRenderbuffer) {
            glDeleteRenderbuffersOES(1, &colorRenderbuffer);
            colorRenderbuffer = 0;
        }
    }
}

- (void)setFramebuffer
{
    if (context) {
        [EAGLContext setCurrentContext:context];

        if (!defaultFramebuffer)
            [self createFramebuffer];

        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

        glViewport(0, 0, framebufferWidth, framebufferHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, framebufferWidth, framebufferHeight, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();


    }
}

- (BOOL)presentFramebuffer
{
    BOOL success = FALSE;

    if (context) {
        [EAGLContext setCurrentContext:context];

        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);

        success = [context presentRenderbuffer:GL_RENDERBUFFER_OES];
    }

    return success;
}

- (void)layoutSubviews
{
    // The framebuffer will be re-created at the beginning of the next setFramebuffer method call.
    [self deleteFramebuffer];
}

@end

testViewController.m

#import "testAppDelegate.h"
#import "testViewController.h"
#import "EAGLView.h"

// Uniform index.
enum {
    UNIFORM_TRANSLATE,
    NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];

// Attribute index.
enum {
    ATTRIB_VERTEX,
    ATTRIB_COLOR,
    NUM_ATTRIBUTES
};
@interface testViewController ()
@property (nonatomic, retain) EAGLContext *context;
@property (nonatomic, assign) CADisplayLink *displayLink;
@end
@implementation PyrotexniViewController
@synthesize animating, context, displayLink;

- (void)awakeFromNib
{
    EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];



    if (!aContext)
        NSLog(@"Failed to create ES context");
    else if (![EAGLContext setCurrentContext:aContext])
        NSLog(@"Failed to set ES context current");

    self.context = aContext;
    [aContext release];

    [(EAGLView *)self.view setContext:context];
    [(EAGLView *)self.view setFramebuffer];
    animating = FALSE;
    animationFrameInterval = 1;
    self.displayLink = nil;

- (void)dealloc
{
    // Tear down context.
    if ([EAGLContext currentContext] == context)
        [EAGLContext setCurrentContext:nil];

    [context release];
    [EAGLView dealloc];
    [self stopAnimation];

    [super dealloc];

}

- (NSInteger)animationFrameInterval
{
    return animationFrameInterval;
}

- (void)setAnimationFrameInterval:(NSInteger)frameInterval
{

    if (frameInterval >= 1) {
        animationFrameInterval = frameInterval;

        if (animating) {
            [self stopAnimation];
            [self startAnimation];
        }
    }
}

- (void)startAnimation
{
    if (!animating) {
        CADisplayLink *aDisplayLink = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)];
        [aDisplayLink setFrameInterval:animationFrameInterval];
        [aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        self.displayLink = aDisplayLink;

        animating = TRUE;
    }
}

- (void)stopAnimation
{

    if (animating) {
        [self.displayLink invalidate];
        self.displayLink = nil;
        animating = FALSE;

    }
}

- (void)drawFrame
{

    [(EAGLView *)self.view setFramebuffer];

    ......draw code here.....




    [(EAGLView *)self.view presentFramebuffer];
}

, основанный на этой схеме проекта, которая должна работать на устройствах opengles 1.1, нонет (этот код работает только на iphone4)!что здесь не так?Помогите мне, пожалуйста.Спасибо.

Ответы [ 2 ]

1 голос
/ 20 ноября 2011

Проблема, вероятно, заключается в просмотре файлов. Вы должны установить его в GLES 1 по умолчанию вместо GLES 2, который по умолчанию в большинстве случаев. это, вероятно, будет иметь что-то вроде

       if ((self = [super initWithCoder:coder]))
   {
       // Get the layer
       CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

       eaglLayer.opaque = TRUE;
       eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

    renderer = [[ES2Renderer alloc] init];

    if (!renderer)
    {
        renderer = [[ES1Renderer alloc] init];

        if (!renderer)
        {
            [self release];
            return nil;
        }
    }

Просто измените ES2Renderer и ES1Renderer. Это говорит о том, что все эти вещи работают для создания EALayer, а затем установить ES2 по умолчанию, и если ES2 не может быть загружен, то вы используете ES1

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

Одной из проблем является то, что CADisplayLink не существует в версиях IOS ранее 3.1.Вы можете обнаружить это в awakeFromNib следующим образом:

NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
     mDisplayLinkSupported = TRUE;      

, а затем в startAnimation вы можете сделать это

    if (mDisplayLinkSupported)
    {
        // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
        // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
        // not be called in system versions earlier than 3.1.

        mDisplayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
        [mDisplayLink setFrameInterval:1];
        [mDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
    else
        mAnimationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)(1.0 / 60.0) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE];

, а в stopAnimation сделать что-то вроде этого:

if (mAnimating)
{
    if (mDisplayLinkSupported)
    {
        [mDisplayLink invalidate];
        mDisplayLink = nil;
    }
    else
    {
        [mAnimationTimer invalidate];
        mAnimationTimer = nil;
    }

    mAnimating = FALSE;
}

Вам также необходимо сделать так, чтобы подпись drawFrame выглядела так, чтобы она могла обрабатывать сообщения AnimationTimer.

- (void) drawFrame:(id)sender

В любом случае, этот код не использует все те же имена переменных, что и у вас, так как я только что скопировал егоиз моего кода, но вы понимаете суть.Кстати, этот код был получен из старого шаблона XCode, который учитывал более старые версии IOS, которые не поддерживали отображаемые ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...