首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Nehe iOS OpenGL ES 2.0 教程第 1 課:環境建置與渲染循環

     編輯:關於C語言

教程簡介

本系列翻譯自 Nehe Gamedev 的 iOS OpenGL ES 2.0 教程,旨在幫助開發者從零建立現代 OpenGL ES 2.0 渲染管線。第 1 課雖無華麗圖形,但詳細解釋了 iOS 應用啟動流程、EAGLView 架構、渲染循環與 Lesson 基類設計,是後續所有課程的基石。

專案架構總覽

專案包含三類核心物件:

  • Objective-C 類別(紫色區塊):Lesson01AppDelegate、EAGLView,負責 iOS 生命週期與 OpenGL Context 管理。
  • C++ 類別(青色區塊):Lesson 基類及其派生類 Lesson01,封裝跨平台渲染邏輯。
  • 啟動入口:main.m → UIApplicationMain → 載入 MainWindow.xib。

類別關係圖

關鍵元件詳細解析

1. AppDelegate:應用生命週期中樞


// Lesson01AppDelegate.h
@class EAGLView;
class Lesson;

@interface Lesson01AppDelegate : NSObject <UIApplicationDelegate> {
@private
    Lesson* lesson;   // 持有渲染邏輯實例
}
@property (nonatomic, retain) IBOutlet UIWindow* window;
@property (nonatomic, retain) IBOutlet EAGLView* glView;
@end

application:didFinishLaunchingWithOptions: 中建立 Lesson01 實例並注入 EAGLView,後續的 applicationDidBecomeActive/applicationWillResignActive 控制渲染循環啟停。

2. EAGLView:OpenGL Context 與渲染循環核心

繼承 UIView,重寫 layerClass 回傳 CAEAGLLayer,使其成為可繪製的 OpenGL 畫布。

Context 建立與 Framebuffer 設定


// initWithCoder
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];

// createFramebuffer
glGenFramebuffers(1, &defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);

glGenRenderbuffers(1, &colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];

glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);

// 可選深度緩衝
if (useDepthBuffer) {
    glGenRenderbuffers(1, &depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
}
glCheckFramebufferStatus(GL_FRAMEBUFFER);  // 驗證完整性

渲染循環驅動:CADisplayLink


- (void)startRenderLoop {
    if (!displayLink) {
        displayLink = [self.window.screen displayLinkWithTarget:self selector:@selector(drawFrame)];
        [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    }
}
- (void)stopRenderLoop {
    if (displayLink) {
        [displayLink invalidate];
        displayLink = nil;
    }
}

CADisplayLink 同步螢幕刷新率(約 60 FPS),將 drawFrame 加入 RunLoop,實現流暢動畫。

每幀繪製流程 drawFrame


- (void)drawFrame {
    if (context) {
        [EAGLContext setCurrentContext:context];
        if (!defaultFramebuffer) [self createFramebuffer];
        glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);

        if (lesson) {
            if (!lessonIsInitialized) {
                lesson->init();
                lessonIsInitialized = YES;
            }
            lesson->draw();  // 委派給 C++ 渲染邏輯
        }

        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
        [context presentRenderbuffer:GL_RENDERBUFFER];  // 送顯示
    }
}

3. Lesson 基類:跨平台渲染介面


// Lesson.h
class Lesson {
public:
    Lesson();
    virtual ~Lesson();
    virtual void init() = 0;           // 資源載入、Shader 編譯等
    virtual void draw() = 0;           // 每幀渲染指令
    virtual void setRenderbufferSize(unsigned int w, unsigned int h);
protected:
    unsigned int m_renderbufferWidth, m_renderbufferHeight;
};

純虛函數強制派生類實作 init/draw,setRenderbufferSize 內呼叫 glViewport 設定繪製區域。

4. Lesson01:最簡渲染——清除畫面為紅色


// Lesson01.mm
void Lesson01::init() {
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);  // RGBA 紅色
}
void Lesson01::draw() {
    glClear(GL_COLOR_BUFFER_BIT);          // 清除色彩緩衝
}

執行結果:全螢幕純紅,證明 OpenGL ES 2.0 管線已正常運作。

開發環境需求

  • Mac OS X + Xcode 4+
  • iOS 4.0+ 真機或模擬器(iPhone 3GS / iPod Touch 3 代以上支援 ES 2.0)
  • 專案碼可在 Google Code 下載

下一課預告

第 2 課將引入 Shader 程式物件、頂點屬性陣列,繪製第一個三角形,正式進入可程式化管線開發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved