2013年1月5日 星期六

OpenGL ES 2.0 tutorial for iOS 6 and Xcode 4.5.2 ﹣Part 1

原本的 tutorial 來自 OpenGL ES 2.0 for iPhone Tutorial,因為在它的實驗裡不是使用 iOS 6 和 Xcode 4.5.2 的版本,所以實際在執行時,遇到了一些問題,導致無法看到正確的結果。就如同我常告訴自己一樣,有不了解的東西時,一定是有觀念不懂,才看不到問題的所在,就像在實驗這個 tutorial 時,從不能執行到最後做出來後,才知道是個簡單的觀念。

實驗開始!參考 OpenGL ES 2.0 for iPhone Tutorial ,首先會遇到找不到 window-based Application 的問題,在 Xcode 4.5.2 已經拿掉,必須改用 Empty Application。




在 Product Name 輸入你想要的 Project 名稱,這裡我使用了 ARC (Automatic Reference Counting),所以不會用到舊版的 autorelease。



建立好 Project 之後,我們先加入需要的 Library:OpenGLES.framework 和 QuartzCore.framework。


接著建立 OpenGLView.h 和 OpenGLView.m,選擇 Object-C Class Template,Class 輸入 OpenGL, Subclass of 輸入 UIView。




修改 OpenGLView.h


#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>

@interface OpenGLView : UIView {
    CAEAGLLayer* _eaglLayer;
    EAGLContext* _context;
    GLuint _colorRenderBuffer;
}

@end

修改 OpenGLView.m

#import "OpenGLView.h"

@implementation OpenGLView

//- (id)initWithFrame:(CGRect)frame
//{
//    self = [super initWithFrame:frame];
//    if (self) {
//        // Initialization code
//    }
//    return self;
//}

/*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.
 - (void)drawRect:(CGRect)rect
 {
 // Drawing code
 }
 */

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

- (void)setupLayer {
    _eaglLayer = (CAEAGLLayer*) self.layer;
    _eaglLayer.opaque = YES;
}

- (void)setupContext {
    EAGLRenderingAPI api = kEAGLRenderingAPIOpenGLES2;
    _context = [[EAGLContext alloc] initWithAPI:api];
    if (!_context) {
        NSLog(@"Failed to initialize OpenGLES 2.0 context");
        exit(1);
    }
    
    if (![EAGLContext setCurrentContext:_context]) {
        NSLog(@"Failed to set current OpenGL context");
        exit(1);
    }
}

- (void)setupRenderBuffer {
    glGenRenderbuffers(1, &_colorRenderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
    [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
}

- (void)setupFrameBuffer {
    GLuint framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, _colorRenderBuffer);
}

- (void)render {
    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    [_context presentRenderbuffer:GL_RENDERBUFFER];
}

// Replace initWithFrame with this
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    NSLog(@"Init");
    if (self) {
        [self setupLayer];
        [self setupContext];
        [self setupRenderBuffer];
        [self setupFrameBuffer];
        [self render];
    }
    return self;
}

// Replace dealloc method with this
//- (void)dealloc
//{
//    [_context release];
//    _context = nil;
//    [super dealloc];
//}

@end


因為我使用了 ARC,所以 dealloc 裡就不需要 [_context release] and [super dealloc]

//    [_context release];
//    [super dealloc];

- (id)initWithFrame:(CGRect)frame 也要記得註解掉 Xcode 幫你加的,使用我們自己的;

修改 AppDelegate.h

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

@interface AppDelegate : UIResponder <UIApplicationDelegate> {
    OpenGLView *_glView;
}

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, retain) IBOutlet OpenGLView *glView;

@end

修改 AppDelegate.m,先加上這一行

@synthesize glView=_glView;

再修改 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    //self.window.backgroundColor = [UIColor whiteColor];
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    self.glView = [[OpenGLView alloc] initWithFrame:screenBounds];
    [self.window addSubview:_glView];
    [self.window makeKeyAndVisible];
    return YES;
}

在我實驗的過程,主要是因為 didFinishLaunchingWithOptions:launchOptions 裡紅色的部份,我以為不需要這一個步驟,但如果不執行這一行,window 就沒有辦法被初始化,執行 addSubview: 也就沒作用了。

底下是執行的結果,本來白色的畫面,透過 OpenGL ES 改變成綠色了!








沒有留言:

張貼留言