GLFun(31)~OpenGL ESテンプレートの利用(6)

2012. 02. 23
OpenGL ES 2.0用のコード部分)

・正射影行列用配列の設定(OpenGL ES 2.0用)

正射影行列用配列proj[ ]の生成には、Apple公式のサンプルコード『GLES2Sample』から流用した変換行列のクラスmatrixにあるmat4f_LoadOrtho関数を使用します。

mat4f_LoadOrthoはOpenGL ES 1.1のglOrthoと同じくビューボリュームの値(left、right、bottom、top、near、far)を指定することで、4×4の正射影行列用配列を作成します。

作成するビューボリュームもオリジナルのGLFunと同じく、左下(0, 0)からビューの(幅, 高さ)の大きさです。

・uniform値の更新の追加(OpenGL ES 2.0用)

glUniformで、描画色と正射影行列、そしてテクスチャの使用フラグのuniform値の設定を行っています。

描画色(UNIFORM_COLOR)は、CGColorGetComponentsで取得した配列componentsをそのまま渡しています。

正射影行列(UNIFORM_PROJECTION_MATRIX)は、上述のmatrixクラス関数で作成したproj[ ]を指定します。

テクスチャ使用のフラグ(UNIFORM_TEXTURE_FLAG)は、デフォルトとして0に設定し、選択図形がImageの時に1に設定されるようにします。

・attribute値の更新の修正(OpenGL ES 2.0用)

テンプレートでは、glVertexAttribPointerによる頂点座標配列(ATTRIB_VERTEX)と頂点色配列(ATTRIB_VERTEX)のポインタの設定と、glEnableVertexAttribArrayによる両頂点配列の有効化を行っていますが、今回は頂点色配列は使用しないので不要になり、また頂点座標配列は選択図形によって異なるので別途指定するので、ここでは頂点座標配列の有効化のみになります。

・テクスチャオブジェクトの解放の修正(OpenGL ES 1.1/2.0共通)

少しでもコードの見通しを良くするため、『GLFun(25)~サンプルコードとの差異』の『テクスチャオブジェクトの有効/無効化』にあるように、3種の単色図形描画時の冒頭にあるテクスチャオブジェクトの解放をglDisableによる無効化に変更します。

・ビューインスタンスへの置換(OpenGL ES 1.1/2.0共通)

頂点座標値を求める演算中、UIKit座標系とOpenGL座標系でY座標の反転を行う際にframeプロパティでビューのフレーム矩形を取得していますが、オリジナルのGLFunではビュークラス(GLFunView)で記述されていたコードのためレシーバが『self』になっているので、上述のビューインスタンスglViewに置換する必要があります。

・頂点配列ポインタの設定(OpenGL ES 2.0用)

OpenGL ES 1.1ではglVertexPointerで頂点配列ポインタを設定しますが、OpenGL ES 2.0では代わりにglVertexAttribPointerで置換します。

3種の図形描画では当該関数の行を置換するだけですが、選択画像がImageの場合はTexture2DクラスのメソッドがOpenGL ES 2.0ではそのまま使えないこともあり、色々書き換える必要があるので別途説明します。

・楕円描画の頂点座標演算の修正(OpenGL ES 1.1/2.0共通)

少しでもコードの見通しを良くするため、『GLFun(25)~サンプルコードとの差異』の『楕円描画の頂点座標生成』にあるように、楕円の半径と原点移動の演算を簡略化しています。

・OpenGL ES 2.0でのテクスチャの貼り付け(OpenGL ES 2.0用)

オリジナルのGLFunでは、画像をテクスチャにしてプリミティブに貼り付けて描画を行う作業はTexture2DクラスのdrawAtPointメソッドで行っていました。
(『GLFun(23)~Texture2Dクラス(12)』参照)

しかしOpenGL ES 2.0の場合、頂点属性配列のポインタをシェーダプログラムに渡す都合上、drawAtPointメソッドに描画をさせるのは色々と面倒なので使用せず、drawFrameメソッド側で描画を行うことにします。

最初にOpenGL ES 2.0を使用しているかどうかを示す、フラグのプロパティuseOpenGLES2をYESにします。

そして指定した画像からテクスチャオブジェクトを生成するTexture2DクラスのinitWithImage:メソッドを呼び出します。
(『GLFun(19)~Texture2Dクラス(8)』参照)

この際に新たに追加した引数として、フラグuseOpenGLES2を渡すようにしています。
(Texture2Dクラスの修正については別途後述します)

これはTexture2Dのインスタンスを生成する際に、暗黙的に呼び出されるTexture2Dクラスのイニシャライザinitializeメソッド内で、OpenGL ES 1.1のみに存在する関数(glTexEnvglEnableClientState)を呼び出しているので、これらの関数呼び出しを回避するために使用します。
(『GLFun(14)~Texture2Dクラス(3)』参照)

その後drawAtPoint:メソッドを呼び出す代わりに、その内容をOpenGL ES 2.0に対応する形式で記述します。

タッチ座標pointは、drawAtPoint:メソッド呼び出し時に渡していた引数そのままの式です。

テクスチャ座標配列coordinates[ ]では、テクスチャ座標系の比を表すプライベートなインスタンス変数(_maxSと_maxT)の代わりに、読み込みのみのプロパティ(maxSとmaxT)を使用しています。

画像の幅widthと高さheightでも、プライベートなインスタンス変数(_widthと_height)の代わりに。読み込みのみプロパティ(pixelsWideとpixelsHigh)を使用しています。

このようにプライベートなインスタンス変数を同内容のプロパティに置き換えているだけで、演算式の内容をそのままコピーしています。

以降の処理に関しては『iPhone/iPadゲーム開発のゲンバから…/OpenGL ES 2.0 ④』を参考に行いました。

正直、内容を理解し切れておらず、ここでの説明には不備や誤りがあると思いますので、元記事を一読することを推奨します。

glUniformによるuniform値の更新では、テクスチャオブジェクト(UNIFORM_TEXTURE)を(おそらく0番目を意味する)0に、(フラグメントシェーダプログラムでの描画色設定の判別用)テクスチャ使用のフラグ(UNIFORM_TEXTURE_FLAG)を1(有効)に設定します。

glVertexAttribPointerによるattribute値の更新では、頂点座標配列(ATTRIB_VERTEX)にvertices、テクスチャ座標配列(ATTRIB_TEXCOORD)にcoordinatesを指定し、glEnableVertexAttribArrayでテクスチャ座標を有効にします。
(頂点座標配列は事前に有効済)

glActiveTextureはアクティブにするテクスチャユニットをしていするもので、(おそらく0番目を意味する)GL_TEXTURE0を指定します。

最後にglDrawArraysでプリミティブを描画します。

glActiveTexture

void glActiveTexture(GLenum texture);

アクティブなテクスチャユニットを選択します。

glActiveTextureは、後続のテクスチャの状態の呼び出しに作用するテクスチャユニットを選択します。

実装がサポートするテクスチャユニット数は実装に依存しますが、少なくとも2である必要があります。

textureがGL_TEXTUREiの一つ(iの範囲は、0から(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1))でない場合、GL_INVALID_ENUMが発生します。

texture:アクティブにするテクスチャユニットを指定します。
テクスチャユニット数は実装に依存しますが、少なくとも2である必要があります。
textureはGL_TEXTUREiの一つ(iの範囲は、0から(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1))である必要があります。
初期値はGL_TEXTURE0です。


OpenGL ES 1.1用のコード部分)

・正射影行列用配列の設定(OpenGL ES 1.1用)

オリジナルのGLFunではOpenGLES2DViewで行っている投影行列へのglOrthoでの正射影行列の適用を追加します。

・描画色の設定(OpenGL ES 1.1用)

glColorによる描画色の設定は、CGColorGetComponentsで取得した配列componentsの内容を要素単位で指定しています。

・頂点座標配列と頂点色配列の修正(OpenGL ES 1.1用)

テンプレートの頂点座標配列と頂点色配列の設定部分ですが、頂点座標配列は各図形描画部分で行うので、配列を有効にするglEnableClientStateのみ残します。

描画色は頂点ごとに設定しませんので、頂点色配列は不要になります。

・画像描画の修正(OpenGL ES 1.1用)

OpenGL ES 2.0での画像描画用に作成したフラグuseOpenGLES2をNOに設定すると共に、initWithImage:メソッドに引数『version:useOpenGLES2』を追加します。


OpenGL ES 1.1と2.0の共通部分)

テンプレートのglDrawArraysは不要ですので削除します。


5)loadShadersメソッドの編集

attribute値の場所の修正と、uniform値の場所を追加します。
(太字が追加修正した部分)

- (BOOL)loadShaders
{
    GLuint vertShader, fragShader;
    NSString *vertShaderPathname, *fragShaderPathname;

    // Create shader program.
    program = glCreateProgram();

    // Create and compile vertex shader.
    vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
    if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname])
    {
        NSLog(@"Failed to compile vertex shader");
        return FALSE;
    }

    // Create and compile fragment shader.
    fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
    if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname])
    {
        NSLog(@"Failed to compile fragment shader");
        return FALSE;
    }

    // Attach vertex shader to program.
    glAttachShader(program, vertShader);

    // Attach fragment shader to program.
    glAttachShader(program, fragShader);

    // Bind attribute locations.
    // This needs to be done prior to linking.

    glBindAttribLocation(program, ATTRIB_VERTEX, "position");
    glBindAttribLocation(program, ATTRIB_TEXCOORD, "texcoord");

    // Link program.
    if (![self linkProgram:program])
    {
        NSLog(@"Failed to link program: %d", program);

        if (vertShader)
        {
            glDeleteShader(vertShader);
            vertShader = 0;
        }
        if (fragShader)
        {
            glDeleteShader(fragShader);
            fragShader = 0;
        }
        if (program)
        {
            glDeleteProgram(program);
            program = 0;
        }

        return FALSE;
    }

    // Get uniform locations.
    uniforms[UNIFORM_COLOR] = glGetUniformLocation(program, "constColor");
    uniforms[UNIFORM_PROJECTION_MATRIX] = glGetUniformLocation(program,
        "projectionMatrix");
    uniforms[UNIFORM_TEXTURE_FLAG] = glGetUniformLocation(program, "flag");
    uniforms[UNIFORM_TEXTURE] = glGetUniformLocation(program, "texture");


    // Release vertex and fragment shaders.
    if (vertShader)
        glDeleteShader(vertShader);
    if (fragShader)
        glDeleteShader(fragShader);

    return TRUE;
}

7805

attribute値の場所では、頂点色を示すATTRIB_COLORが不要なので削除し、新たにテクスチャ座標を示すATTRIB_TEXCOORDを追加します。

uniform値の場所はglGetUniformLocationを使用して、描画色UNIFORM_COLORと正射影行列UNIFORM_PROJECTION_MATRIX、テクスチャ使用のフラグUNIFORM_TEXTURE_FLAG、そしてテクスチャオブジェクトUNIFORM_TEXTUREを指定します。


6)タッチイベントメソッドの編集

3つのタッチイベントメソッド内のビュー指定の修正と、描画メソッドの呼び出しの修正を行います。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    EAGLView *glView = (EAGLView *)self.view;

    if (useRandomColor)
        self.currentColor = [UIColor randomColor];
    UITouch *touch = [[event touchesForView:glView] anyObject];
    firstTouch = [touch locationInView:glView];
    lastTouch = [touch locationInView:glView];

    [self drawFrame];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    EAGLView *glView = (EAGLView *)self.view;

    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:glView];
    [self drawFrame];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    EAGLView *glView = (EAGLView *)self.view;

    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:glView];
    [self drawFrame];
}

7806

3つのタッチイベントメソッド(touchesBegan:withEvent:touchesMoved:withEvent:touchesEnded:withEvent:)は、オリジナルのGLFunではビュークラス(GLFunView)で記述されていたコードのため、touchesForView:メソッドとlocationInView:メソッドのレシーバが『self』になっているので、それぞれビューのインスタンスglViewを生成して置換します。

またタッチイベント発生時に呼び出す描画メソッドが、オリジナルのGLFunではdrawメソッドなのでdrawFrameメソッドに修正します。



参考文献

iPhone/iPadゲーム開発のゲンバから…/OpenGL ES 2.0 ④

OpenGL ES 2.0 Reference Pages

はじめてのiPhone3プログラミングはじめてのiPhone3プログラミング
(2009/12/17)
Dave Mark、Jeff LaMarche 他

商品詳細を見る

Beginning Ios 6 Development: Exploring the Ios SdkBeginning Ios 6 Development: Exploring the Ios Sdk
(2012/12/26)
David Mark、Jack Nutting 他

商品詳細を見る






bose_soundsport_free
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
09 | 2017/10 | 11
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

bose_soundsport_free
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR