GLSL~4.5.2 精度修飾子

2012. 01. 31
4.5.2 精度修飾子

浮動小数点や整数の宣言は、型の前に精度修飾子を一つ持つことができます。

修飾子意味
highp上記で述べた頂点言語の最小要件を満たします。
オプションでフラグメント言語を入れられます。
mediump上記のフラグメント言語の最小要件を満たしています。
範囲と精度は、lowpで提供された以上でhighpで提供された以下になります。
lowpmediump未満の範囲と精度ですが、全てのカラーチャンネルの全ての色値を
表現できるように意図しています。

例:

lowp float color;
varying mediump vec2 Coord;
lowp ivec2 foo(lowp mat3);
highp mat4 m;

精度修飾子は、基盤となる実装で変数を格納する時に使用する必要がある、最小範囲と精度を宣言します。

実装では要求よりも大きな範囲と精度が使用されますが、変わりありません。

特定の精度修飾子の実装に使用される増加の範囲と精度の量は、変数、および変数に関する操作と、他の実装依存の詳細に依存することができます。

精度修飾子に必要な最小範囲と精度は、

修飾子浮動小数点の範囲浮動小数点の大きさの範囲浮動小数点の精度整数の範囲
highp(-262, 262)(2-62, 262)相対: 2-16(-216, 216)
mediump(-214, 214)(2-14, 214)相対: 2-10(-210, 210)
lowp(-2, 2)(2-8, 2)絶対: 2-8(-28, 28)

ここで浮動小数点の大きさの範囲とは、ゼロ以外の値の大きさの範囲です。

浮動小数点の精度の場合は、全てのゼロ以外の値のため、任意の値からその値へ相対的に比較した相対精度を意味します。

全ての精度レベルで、ゼロを正確に表現する必要があります。

整数型の場合は、指定された範囲内の全ての整数値を表す必要があります。

実装がコンパイルユニット内の変数のストレージのために宣言された精度を提供できない場合、結果をコンパイルまたはリンクエラーにする必要があります。

高と中精度では、整数の範囲は同じ精度修飾子の浮動小数点値に対応することによって、正確に表現できるようにする必要があります。

つまりhighp inthighp floatで表すことができ、mediump intmediump floatで表すことができます。

ただし、lowp intlowp floatで表すことはできません。

頂点言語は、lowpmediump、そしてhighpのいずれを使用してコンパイルとリンクを行っても、エラー無しである必要があります。

フラグメント言語は、lowpmediumpを使用してコンパイルしてもエラー無しである必要があります。

highpのサポートはオプションです。

実装によって提供される実際の範囲と精度は、APIを介して照会することができます。

リテラル定数には精度修飾子はありません。

どちらもブール変数は実行しません。

コンストラクタの引数が精度修飾子を持っていない場合、浮動小数点値コンストラクタも整数コンストラクタも実行されません。

この項の場合、『演算』は演算子、組み込み関数、コンストラクタを含み、『オペランド』は関数の引数とコンストラクタの引数を含みます。

精度は内部的に数値を求める演算に使用され、その精度の能力はその後に続くその結果として生じる中間値に関連付けされるため、演算によって消費されるオペランドの能力は少なくとも最高精度と同じ高さにする必要があります。

精度が定義されていない定数式と部分式の場合、評価は実行時の、またはサポートされているターゲット(mediumpまたはhighpのどちらか)の精度の最高以上で実行されます。

定数式の評価は不変である必要があり、通常はコンパイル時に実行されます。

オペランドが適切な精度修飾子を持っていない場合、精度の能力は他のオペランドから取得します。

オペランドが精度修飾子を持っていない場合、式中の次に消費される演算のオペランドの精度の能力が使用されます。

このルールは精度修飾されたオペランドが見つかるまで、再帰的に適用されます。

必要に応じて、割り当てのためのl値や、イニシャライザのための宣言された変数、関数呼び出しの引数の仮パラメータ、または関数が返す関数の戻り値の型といった精度の能力が含まれます。

精度がこの方法によって決定することができない、すなわち式全体が精度修飾子を持たないオペランドのみで構成されている場合、結果は割り当てられない、または引数として渡されず、型のデフォルトの精度以上で評価されます。

フラグメントシェーダでこれが発生する場合、デフォルトの精度を定義する必要があります。

例えば、文を考えてみます。

uniform highp float h1;     
highp float h2 = 2.3 * 4.7;// 演算と結果がhighp精度
mediump float m; 
m = 3.7 * h1 * h2;// 全ての演算がhighp精度
h2 = m * h1;// 演算はhighp精度
m = h2 – h1;// 演算はhighp精度
h2 = m + m;// 加算と結果はmediump精度
void f(highp float p); 
f(3.3);// 3.3はhighp精度で渡されます

浮動小数点演算の結果が格納に必要な精度より大きい(小さい)場合、結果はその精度が表現できる最大値(最小値)、あるいは無限大(負の無限大)表現にすることができます。

それ結果は、動作のラッピングや、NaN(Not a Number:非数)の発生、または例外条件などになることができません。

同様に、結果が結果の精度を格納できるよりもゼロに近い場合、結果はゼロまたは(正確に符号を付けられた)無限小値の表現である必要があります。

整数がオーバーフローした結果は未定義の値です。

それはラップされる、またはラップされない可能性があります。

精度修飾子は他の修飾子と同様に、変数の基本型に影響しません。

特に、精度の変換にはコンストラクタは無く、コンストラクタは型のみを変換します。

また精度修飾子は他の修飾子と同様に、パラメータの型に基づく関数のオーバーロードに寄与しません。

次章で説明するように、関数の入力と出力はコピーを介して行われるので、修飾子が一致する必要はありません。



参考文献

The OpenGL ES Shading Language 1.0.17

Wikipedia/NaN

UIDeviceクラス

2012. 01. 30
●概要

UIDeviceクラスは現在のデバイスを表すシングルトンのインスタンスを提供します。

このインスタンスから、割り当てられた名前、デバイスモデル、オペレーティングシステム名とバージョンなど、デバイスについての情報を取得することができます。

またUIDeviceのインスタンスを使用して、物理的な向きなどデバイス特性の変化を検出します。

現在の向きはorientationプロパティを使用するか、UIDeviceOrientationDidChangeNotification通知を受ける登録をすることによって変更通知を受け取って取得します。

向きデータを取得するこれらの技術を使用する前に、beginGeneratingDeviceOrientationNotificationsメソッドを使用してデータの配信を有効にする必要があります。

デバイスの向きの追跡をする必要が無くなった場合は、通知の配信を無効にするendGeneratingDeviceOrientationNotificationsメソッドを呼び出します。

同様にバッテリの充電状態の変化(batteryStateプロパティ)、または充電レベル(batteryLevelプロパティ)についての情報や通知の取得にUIDeviceのインスタンスを使用することができます。

またUIDeviceのインスタンスは近接センサの状態(proximityStateプロパティ)へのアクセスも提供します。

近接センサはユーザの持つデバイスが顔に近づいたかどうかを検出します。

バッテリ監視や近接検知は必要な場合のみ有効にします。

iOS 4.2以降では、カスタム入力やキーボードアクセサリビューで、キーボード入力のクリック音を再生するplayInputClickインスタンスメソッドを使用することができます。



●タスク

●共有デバイスインスタンスの取得


+ currentDevice

●使用可能機能の決定


  multitaskingSupported    property

●デバイスとオペレーティングシステムの識別


  name    property
  systemName    property
  systemVersion    property
  model    property
  localizedModel    property
  userInterfaceIdiom    property
  uniqueIdentifier    property    iOS 5.0では非推奨

●デバイスの向きの取得


  orientation    property
  generatesDeviceOrientationNotifications    property
– beginGeneratingDeviceOrientationNotifications
– endGeneratingDeviceOrientationNotifications

●デバイスのバッテリ状態の取得


  batteryLevel    property
  batteryMonitoringEnabled    property
  batteryState    property

●近接センサの使用


  proximityMonitoringEnabled    property
  proximityState    property

●入力クリックの再生


– playInputClick



●プロパティ

Objective-Cのプロパティについての詳細は、『The Objective-C Programming Language』の『Properties』を参照してください。

orientation

@property (nonatomic, readonly) UIDeviceOrientation orientation

デバイスの物理的な方向を返します。(読み込みのみ)

プロパティの値は、デバイスの現在の方向を示す定数です。

この値はデバイスの物理的な方向を表しますが、アプリケーションのユーザインターフェイスの現在の方向とは異なる場合があります。

有効な値の説明は『UIDeviceOrientation』を参照してください。

このプロパティの値は、beginGeneratingDeviceOrientationNotificationsを呼び出すことによって方向の通知が有効になっている場合を除いて、常に0を返します。


systemVersion

@property (nonatomic, readonly, retain) NSString *systemVersion

オペレーティングシステムの現在のバージョンです。(読み込みのみ)

システムバージョンの例:@"1.2"。



●クラスメソッド

currentDevice

+ (UIDevice *)currentDevice

現在のデバイスを表すオブジェクトを返します。

戻り値は現在のデバイスを表すシングルトンオブジェクトです。

デバイスについての情報を取得するには、返されたUIDeviceのインスタンスのプロパティにアクセスします。

デバイスの通知の受け取りを登録する前に、UIDeviceのインスタンスを示す必要があります。



●インスタンスメソッド



●定数

UIDeviceOrientation

デバイスの物理的な方向。

typedef enum {
    UIDeviceOrientationUnknown,
    UIDeviceOrientationPortrait,
    UIDeviceOrientationPortraitUpsideDown,
    UIDeviceOrientationLandscapeLeft,
    UIDeviceOrientationLandscapeRight,
    UIDeviceOrientationFaceUp,
    UIDeviceOrientationFaceDown
} UIDeviceOrientation;

UIDeviceOrientationUnknown
デバイスの方向が決定できません。

UIDeviceOrientationPortrait
デバイスはポートレートモードで、デバイスが垂直でホームボタンが下部にある持ち方です。

UIDeviceOrientationPortraitUpsideDown
デバイスはポートレートモードですが逆さまで、デバイスが垂直でホームボタンが上部にある持ち方です。

UIDeviceOrientationLandscapeLeft
デバイスはランドスケープモードで、デバイスが垂直でホームボタンが右側にある持ち方です。

UIDeviceOrientationLandscapeRight
デバイスはランドスケープモードで、デバイスが垂直でホームボタンが左側にある持ち方です。

UIDeviceOrientationFaceUp
デバイスが地面と平行で、画面が上方を向いている持ち方です。

UIDeviceOrientationFaceDown
デバイスが地面と平行で、画面が下方を向いている持ち方です。

orientationプロパティはデバイスの方向の識別に、これらの定数を使用します。

これらの定数はデバイスの物理的な方向を識別しますが、アプリケーションのユーザインターフェイスの方向とは連動しません。



●通知



参考文献

UIDevice Class Reference

GLSL~4.3 ストレージ修飾子

2012. 01. 23
4.3 ストレージ修飾子

変数の宣言は、型の前に指定した修飾子を持つ場合があります。

これらの要約を下表に示します。

修飾子意味
< none: default>ローカルでのメモリへの読み込み/書き込み、または関数への入力パラメータ
constコンパイル時の定数、または読み込みのみの関数のパラメータ
attributeOpenGL ESの頂点単位のデータと、頂点シェーダ間で連関するパラメータ
uniformプリミティブの処理において変更しない値で、uniformはアプリケーションと
OpenGL ES、シェーダ間で連関するパラメータ
varyingデータ補間のため、頂点シェーダとフラグメントシェーダ間で連関するパラメータ

ローカル変数は、ストレージ修飾子constのみ使用することができます。

関数のパラメータは、constストレージ修飾子のみ使用することができます。

パラメータの修飾子についての詳細は、『項6.1.1 関数呼び出しの規約』で説明しています。

関数の戻り型と構造体のフィールドにストレージ修飾子を使用しないでください。

あるシェーダの実行から次の実行への伝達(フラグメントシェーダ間または頂点シェーダ間の伝達)のためのデータ型は存在しません。

これにより、複数の頂点またはフラグメントの同じシェーダ上での並列実行を防ぐことができます。

ストレージ修飾子を持たないグローバルの宣言、または単なるconst修飾子はイニシャライザを含めることができ、その場合はmain()関数の最初の行が実行される前に初期化されます。

イニシャライザは定数式である必要があります。

アプリケーションによって初期化されていない、または宣言で初期化されていないストレージ修飾子を持たないグローバル変数はOpenGL ESで初期化せず、むしろ未定義値はmain()で入力します。

uniform、attribute、varyingはイニシャライザを持っていない場合があります。


4.3.1 デフォルトのストレージ修飾子

グローバル変数に修飾子が無い場合、その変数はアプリケーション、または他のプロセッサ上で実行されているコンパイルユニットとの連関を持っていません。

グローバルまたはローカルの非修飾変数の宣言では、ターゲットとするプロセッサに関連付けられたメモリが割り当てられます。

この変数は、割り当てられたメモリへの読み込み/書き込みアクセスを提供します。


4.3.2 const修飾子

名付けられたコンパイル時の定数は、const修飾子を使用して宣言することができます。

定数として修飾された全ての変数は、コンパイルユニットのための読み込みのみの変数です。

定数として宣言された変数は、組み込み数値定数を使用するよりも、より分かり易いシェーダにすることができます。

const修飾子は、基本のデータ型の全てで使用することができます。

宣言外でconst変数に書き込みを行うとエラーになるので、宣言時に初期化する必要があります。

例:

const vec3 zAxis = vec3 (0.0, 0.0, 1.0);

構造体のフィールドは、constで修飾されていない場合があります。

構造体変数はconstとして宣言し、構造体のコンストラクタで初期化することができます。

constのイニシャライザの宣言は、定数式である必要があります。

配列を含む配列と構造体は、初期化できないために定数宣言されていない場合があります。

『5.10 定数式』を参照してください。


4.3.3 attribute

attribute修飾子は、頂点ごとにOpenGL ESから頂点シェーダへ渡される変数の宣言に使用されます。

頂点シェーダ以外のシェーダのタイプでattribute変数を宣言するとエラーになります。

attribute変数は、頂点シェーダに関しては読み込みのみとなっています。

attribute変数の値は、OpenGL ESの頂点APIを介して、または頂点配列の一部として頂点シェーダに渡されます。

頂点シェーダに頂点属性を伝達すると、全ての頂点シェーダの実行上で変更されると期待されています。

attribute修飾子は、floatvec2vec3vec4mat2mat3、そしてmat4のデータ型でのみ使用することができます。

attribute変数は、配列または構造体として宣言することはできません。

宣言の例:

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texCoord;

グラフィックスハードウェアは、頂点属性を渡すための固定された場所の数が少ないと予想されます。

したがって、OpenGL ESシェーディング言語は4つの浮動小数点値(すなわち、vec4)までの空間を持つものとして各非行列の属性変数を定義しています。

使用することができるattribute値の数は実装依存で制限されており、それを超えた場合はリンクエラーが発生します。
(宣言したattribute値が使用されていない場合は、この制限に対してカウントされません)

float attributeはvec4としてこの制限に対して同じ量をカウントするので、アプリケーションは基盤をなすハードウェアの機能をより良く利用するため、vec4に関連の無い4つのfloat attributeをグループにパックしてまとめる検討をしてください。

mat4 attributeは4つのvec4 attribute変数の場所に相当する分を消費し、mat3は3つのattribute変数の場所に相当する分を消費、そしてmat2は2つのattribute変数の場所を消費します。

行列によってこの空間をどのように利用しているかはAPIと言語を介して実装によって隠蔽されています。

attribute変数はグローバルスコープを持っている必要があります。


4.3.4 uniform

uniform修飾子は、プリミティブ全体の処理に渡って同じ値となるグローバル変数の宣言に使用します。

全てのuniform変数は読み込みのみで、APIコマンドによってアプリケーションで直接、またはOpenGL ESによって間接的に初期化されます。

宣言の例:

uniform vec4 lightPosition;

uniform修飾子は基本的なデータ型や型が構造体またはこれらの配列の宣言で使用することができます。

シェーダの各タイプで使用することができるuniformのストレージ量は実装依存で制限されており、 
それを超えた場合はコンパイル時またはリンク時にエラーが発生します。

宣言したuniform変数が静的に使用されていない場合は、この制限に対してカウントされません。

静的な使用とは、シェーダが事前処理後の変数への参照を含むことを意味します。

シェーダ内で静的に使用できるユーザ定義のuniform変数の数と組み込みのuniform変数の数は、利用できるuniformストレージを超えるかどうかを判断するために一緒に追加されます。

頂点とフラグメントのシェーダが一緒にリンクされている場合、単一のグローバルuniform名前空間を共有することになります。

したがって、同名のuniformの型と精度は、単一の実行可能オブジェクトにリンクされている全てのシェーダ間で一致している必要があります。


4.3.5 varying

varying変数は、頂点シェーダ、フラグメントシェーダ、そして固定機能間のインターフェイスを提供します。

頂点シェーダは頂点ごとに(色やテクスチャ座標などの)値を計算し、varying修飾子で宣言された変数に書き込みます。

また頂点シェーダはvarying変数が書き込まれた同じ値を取得し、読み込むことができます。

頂点シェーダ内のvarying変数の読み込みは、書き込み前に読み込みを行うと未定義を返します。

定義により、varying変数はプリミティブを透視変換補正したレンダリングで、頂点ごとに設定されます。

シングルサンプリングの場合、補間値はフラグメントの中央になります。

マルチサンプリングの場合、補間値はフラグメントの中央またはフラグメントサンプルの一つを含め、ピクセル内のどこでもできます。

フラグメントシェーダはプリミティブ内のフラグメントの位置の関数として、varying変数から読み込み、読み込んだ値を補間値にすることができます。

フラグメントシェーダはvarying変数に書き込むことはできません。

頂点シェーダとフラグメントシェーダの両方で宣言されている同名のvarying変数の型は一致している必要があり、でなければリンクコマンドが失敗します。

varying変数の精度は一致する必要はありません。

フラグメントシェーダで静的使用(すなわち、読み込み)のみのvarying変数は、頂点シェーダ内で宣言する必要があります。
(頂点シェーダ内での余剰なvarying変数の宣言は許容されています)

頂点とフラグメントのシェーダ内でvaryingを照合する規約の要約を下表に示します。

 フラグメントシェーダ
参照無し宣言:非静的使用宣言:静的使用
頂点シェーダ参照無し許可許可エラー
宣言:非静的使用許可許可許可(値は未定義)
宣言:静的使用許可許可許可(値は潜在的に未定義)

静的な使用とは、シェーダが事前処理後にvaryingにアクセスする文が、たとえその文が実際に実行されることはなくても、少なくとも一つ含まれることを意味します。

varying変数は以下のように宣言されます。

varying vec3 normal;

varying修飾子は、floatvec2vec3vec4mat2mat3mat4、またはこれらの配列のデータ型でのみ使用することができます。

構造体はvaryingにすることはできません。

varying変数はグローバルスコープを持っている必要があります。



参考文献

The OpenGL ES Shading Language 1.0.17

GLSL~4.1 基本の型

2012. 01. 22
4.1 基本の型

OpenGL ESシェーディング言語がサポートする基本的なデータ型を下表に示します。

 型 意味
 void 値を返さない関数、または空のパラメータリスト用 
 bool 条件型、trueまたはfalseの値を取る
 int 符号付き整数
 float 単精度浮動小数点スカラー
 vec2 2要素の浮動小数点ベクトル
 vec3 3要素の浮動小数点ベクトル
 vec4 4要素の浮動小数点ベクトル
 bvec2 2要素のブールベクトル
 bvec3 3要素のブールベクトル
 bvec4 4要素のブールベクトル
 ivec2 2要素の整数ベクトル
 ivec3 3要素の整数ベクトル
 ivec4 4要素の整数ベクトル
 mat2 2×2の浮動小数点行列
 mat3 3×3の浮動小数点行列
 mat4 4×4の浮動小数点行列
 sampler2D 2Dテクスチャへアクセスするハンドル
 samplerCube  キューブマップテクスチャへアクセスするハンドル 

更に、シェーダはこれらの配列や構造体を使用して結合し、より複雑な型を構築することができます。

これらにポインタ型はありません。


4.1.1 void型

void型は関数の戻り型、または空の形式的、あるいは実際のパラメータリストとしてのみ使用することができます。


4.1.2 ブール型

コードの条件付き実行を容易に表すため、bool型がサポートされています。

ハードウェアが直接この型の変数をサポートしているとは予想していません。

それは真のブール型とは、trueかfalseのどちらかを意味する2つの値の内の1つのみを持っています。

truefalseの2つのキーワードは、ブール定数として使用することができます。

ブール値の宣言とオプションでの初期化は、以下の例のようになります。

bool success;    // ブール値『success』の宣言
bool done = false;    // ブール値『done』の宣言と初期化

代入演算子『=』の右側には、型がboolで表現される式を指定します。

条件分岐(iffor?:whiledo-while)を使用する式では、bool型で評価する必要があります。


4.1.3 整数型

integer型は主にプログラミングの補助としてサポートされています。

ハードウェアレベルでは、実際の整数はループと配列の指標と、テクスチャユニットへの参照を効率的に実装するための補助となります。

しかし、ハードウェア内での整数型への言語マップの、整数としての要件を気にする必要はありません。

基盤となるハードウェアが、整数演算の広い範囲を完全にサポートしているとは予想していません。

OpenGL ESシェーディング言語の実装では、整数を浮動小数点に変換する操作があります。

したがって、移植のラッピング動作はありません。

整数の宣言とオプションでの初期化は以下の例のようになります。

int i, j = 42;

リテラル整数の定数は、下記のように10進数(基数10)、8進数(基数8)、または16進数(基数16)で表すことができます。

整数定数:
 10進数定数
 8進数定数
 16進数定数

10進数定数:
 ゼロ以外の数字
 10進数定数 数字

8進数定数:
 0
 8進数定数 8進数の数字

16進数定数:
 0x 16進数の数字
 0X 16進数の数字
 16進数定数 16進数の数字

数字:
 0
 ゼロ以外の数字

ゼロ以外の数字:いずれか1つ
 1 2 3 4 5 6 7 8 9

8進数の数字:いずれか1つ
 0 1 2 3 4 5 6 7

16進数の数字:いずれか1つ
 0 1 2 3 4 5 6 7 8 9
 a b c d e f
 A B C D E F


空白は整数定数の数字間では許可されておらず、先頭が0の以降、または定数の先頭が0x0Xの以降も含みます。

先頭の単一のマイナス記号『-』は、算術単項反転として解釈され、定数の一部ではありません。

接尾辞文字はありません。


4.1.4 浮動小数点型

float型は、様々なスカラー演算で使用することができます。

浮動小数点変数は以下の例のように定義されています。

float a, b = 1.5;

0で割るような条件の処理の結果は未定義ですが、処理の中断や終了させてはいけません。

浮動小数点定数は以下のように定義されています。

浮動小数点定数:
 少数定数 指数部分opt
 数字数列 指数部分

少数定数:
 数字数列. 数字数列
 数字数列.
 . 数字数列

指数部分:
 e 符号opt 数字数列
 E 符号opt 数字数列

符号:いずれか一つ
 + -

数字数列:
 数字
 数字数列 数字

指数部分が存在する場合、小数点『.』は必要ありません。

空白は小数点定数内の文字間では許可されていません。

先頭の単一のマイナス記号『-』は、算術単項反転として解釈され、定数の一部ではありません。


4.1.5 ベクトル

OpenGL ESシェーディング言語は、浮動小数点値、整数値、またはブール値の2-、3-、4-要素のベクトルを持つ汎用的なデータ型を含んでいます。

浮動小数点ベクトル変数は、色、法線、位置、テクスチャ座標、テクスチャルックアップの結果など、コンピュータグラフィックスで非常に有用な様々な値の格納に使用することができます。

ブールベクトルは、数値ベクトルを要素ごとに比較するために使用することができます。

シェーディング言語の一部としてベクトルを定義すると、ベクトル処理を行うグラフィックスハードウェア上のベクトル操作のマッピングを直接行うことができます。

一般的には、アプリケーションはスカラー値よりもベクトルによる計算を行うことによって、グラフィックスハードウェアでの並列処理を活用することができます。

ベクトルの宣言の例をいくつか示します。

vec2 texcoord1, texcoord2;
vec3 position;
vec4 myRGBA;
ivec2 textureLookup;
bvec3 lessThan;

ベクトルの初期化は、後で簡単に説明するコンストラクタで行うことができます。


4.1.6 行列

行列はコンピュータグラフィックスにおけるもう一つの有用なデータ型で、OpenGL ESシェーディング言語は浮動小数点値の2×2、3×3、そして4×4行列のサポートを定義しています。

行列は列優先順で読み込みと書き込みを行います。

行列宣言の例:

mat2 mat2D;
mat3 optMatrix;
mat4 view, projection;

行列値の初期化はコンストラクタで行われます。
(『項5.4 コンストラクタ』で説明しています)


4.1.7 サンプラ

sampler2Dなどの)サンプラ型は、効果的なテクスチャへの不透過なハンドルです。

これらはテクスチャへのアクセスを指定する、(『項8.7 テクスチャルックアップ関数』で説明している)組み込みのテクスチャ関数で使用されています。

これらは関数のパラメータやuniform(『項4.3.4 uniform』参照)としてのみ宣言することができます。

テクスチャルックアップ関数のパラメータ、配列のインデックス、構造体のフィールドの選択と挿入以外では、サンプラは式中のオペランドとして許可していません。

サンプラはl-値として扱ったり、outまたはinout関数のパラメータとして使用することはできません。

これらの制限はまた、サンプラ型を含む構造体にも適用されます。

uniformとしては、これらはOpenGL ES APIで初期化されます。

関数パラメータとしては、サンプラは一致する型のサンプラへのみ渡すことができます。

シェーダが実行される前に、シェーダのテクスチャのアクセスとOpenGL ESのテクスチャの状態との間で、整合性のチェックが可能になります。


4.1.8 構造体

ユーザ定義型は、structキーワードを使用して、構造体に他の既に定義された型を集約して定義することができます。

例えば、

struct light {
    float intensity;
    vec3 position;
} lightVar;

この例では、lightは新しい型名となり、lightVarはlight型の変数となります。

新しい型の変数を宣言するには、(structキーワードを除いて)名前を使用します。

light lightVar2;

より正式には、構造体は以下のように宣言されています。

ただし、完全に正確な文法は『節9 シェーディング言語文法』に記述されています。

構造体定義:
 修飾子opt struct 名前opt { メンバリスト } 宣言子opt;

メンバリスト:
 メンバ宣言;
 メンバ宣言 メンバリスト;

メンバ宣言:
 基本型 宣言子;

名前はユーザ定義型で、この新しい型になる変数の宣言に使用することができます。

名前は、他の変数、型や関数と同じ名前空間を共有します。

名前が不可視な変数、型、コンストラクタ、または関数は、全て予め可視になります。

オプションの修飾子は宣言でのみ適用され、名前のために定義される型の一部ではありません。

構造体は少なくとも一つのメンバを宣言する必要があります。

メンバの宣言子は精度の修飾子を含めることができますが、他の修飾子を含めることはできません。

ビットフィールドはサポートされていません。

メンバ型は事前に(前方参照と組み込み定義が無いもので)定義されている必要があります。

メンバ宣言は初期化を含めることができません。

メンバ宣言は配列を含めることができます。

配列はサイズを指定し、そのサイズはゼロより大きい整数定数式である必要があります。
(※原文では『項4.3.3 整数定数式』を参照とありますが、『項4.3.3』は『attribute修飾子』であり、『整数定数式』に該当するような項目はありません)

各構造体のレベルは、メンバ宣言内で指定された名前のための独自の名前空間を持ち、名前は名前空間内で一意である必要があります。

匿名構造体の宣言(型が構造体のメンバ宣言であるが、宣言されていない)はサポートされていません。

struct S
{
    int x;
};

struct T
{
    S;    // エラー:匿名構造体は許可されていない
    int y;
};

組み込み構造体の宣言はサポートされていません。

例1:

struct S
{
    struct T    // エラー:組み込み構造体の定義はサポートされていない
    {
        int a;
    } t;
    int b;
};

例2:

struct T
{
    int a;
};

struct S
{
    T t;    // ok.
    int b;
};

構造体は、『項5.4.3 構造体のコンストラクタ』で説明されているように、宣言時にコンストラクタを使用して初期化することができます。

型や修飾子の使用に関する制限もまた、その型や修飾子を含む構造体に適用されます。

これは再帰的に適用されます。


4.1.9 配列

同じ型の変数は名前に続けてサイズを角括弧『[ ]』で囲む宣言によって、配列に集約することができます。

配列のサイズはゼロより大きい整数定数式である必要があります。
(※原文では『項4.3.3 整数定数式』を参照とありますが、『項4.3.3』は『attribute修飾子』であり、『整数定数式』に該当するような項目はありません)

宣言されたサイズ以上の整数定数式の配列インデックスは受け付けません。

また、負の定数式の配列インデックスも受け付けません。

関数宣言内の仮パラメータとして配列を宣言する場合は、サイズを定義する必要があります。

一次元配列のみ宣言することができます。

全ての基本型と構造体は、配列を作ることができます。

いくつかの例を以下に示します。

float frequencies[3];
uniform vec4 lightPosition[4];

const int numLights = 2;
light lights[numLights];

シェーダ内で宣言時に配列を初期化する機構はありません。

非定数インデックスの配列からの読み込み、または配列への書き込みで、ゼロ未満または配列サイズ以上の場合、動作の結果は未定義です。

この未定義の動作の結果は、プラットフォームに依存します。

基盤システムが不安定になったり、メモリの破損に繋がる可能性があります。

しかし、特定のプラットフォームではそのような事態になる動作を起こさない場合があります。



参考文献

The OpenGL ES Shading Language 1.0.17

GLFun(25)~サンプルコードとの差異

2012. 01. 19
これまで説明した初版の内容と原著のサンプルコード(iOS 3.x版は『Beginning iPhone 3 Development Exploring the iPhone SDK』、iOS 4.x版は『Beginning iPhone 4 Development Exploring the iOS SDK』)との差異を見てみます。


●Texture2Dオブジェクトspriteの生成とバインド

画像描画に用いるTexture2Dオブジェクトspriteの生成とバインドですが、初版ではdrawメソッド内の画像選択時の場合に行っていますが、iOS 3.x版とiOS 4.x版ではビューの初期化を行っているinitWithCoder:内で行っています。

- (id)initWithCoder:(NSCoder*)coder {
    if (self = [super initWithCoder:coder]) {
        currentColor = [[UIColor redColor] retain];
        useRandomColor = NO;
        sprite = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"iphone.png"]];
        glBindTexture(GL_TEXTURE_2D, sprite.name);

    }
    return self;
}


●テクスチャオブジェクトの有効/無効化

初版の本文中の説明では、図形描画では不要なテクスチャオブジェクトを常時保持したくないという理由から、画像描画選択時にテクスチャオブジェクトを生成し、図形描画選択時にテクスチャオブジェクトを破棄を行っています。

しかしiOS 3.xとiOS 4.x版では、上記の通りビューの初期化時にテクスチャオブジェクトを生成・バインドし、図形描画時はglDisableでテクスチャを無効に、画像描画時はglEnableでテクスチャを有効にという処理に簡略化しています。

    switch (shapeType) {
        case kLineShape: {
            glDisable(GL_TEXTURE_2D);
            (中略)
            break;
        }
        case kRectShape: {
            glDisable(GL_TEXTURE_2D);
            (中略)
            break;
        }
        case kEllipseShape: {
            glDisable(GL_TEXTURE_2D);
            (中略)
            break;
        }
        case kImageShape:
            glEnable(GL_TEXTURE_2D);
            [sprite drawAtPoint:CGPointMake(lastTouch.x, self.frame.size.height - lastTouch.y)];
            break;
        default:
            break;
    }

単にコードを簡略化したかったのか、生成/破棄のリソース使用量や実行速度の都合かは分かりませんが、こういうやり方もあるようです。


●楕円描画の頂点座標生成

iOS 4.x版では、楕円の頂点座標生成において計算の簡略化が図られています。

楕円の半径)

初版とiOS 3.x版ではx軸の楕円の半径xradiusを求める際、始点と終点のx座標の大きさを比較し、それに応じて正の始点と終点の差を求めて半分にしていました。

xradius =(firstTouch.x > lastTouch.x) ?

(firstTouch.x - lastTouch.x)/2 :

(lastTouch.x - firstTouch.x)/2;

iOS 4.x版では、C言語の数学関数にある浮動小数点値の絶対値を求めるfabsfを使用し、単純に差の絶対値を求めて半分にしています。

xradius = fabsf((firstTouch.x - lastTouch.x) / 2);

y座標では、初版とiOS 3.x版ではy座標を反転してから始点と終点のy座標の大きさを比較し、それに応じて正の始点と終点の差をy座標を反転して求めて半分にしていました。

yradius =(self.frame.size.height - firstTouch.y > self.frame.size.height - lastTouch.y) ?

((self.frame.size.height - firstTouch.y) - (self.frame.size.height - lastTouch.y))/2 :

((self.frame.size.height - lastTouch.y) - (self.frame.size.height - firstTouch.y))/2;

iOS 4.x版では半径を求めるのにy座標を反転する必要が無いことから、x座標と同じく単純に差の絶対値を求めて半分にしています。

yradius = fabsf((firstTouch.y - lastTouch.y) / 2);

原点の移動)

楕円の原点座標を移動するためのオフセットですが、x座標は変わりません。

xOffset = (firstTouch.x > lastTouch.x) ? lastTouch.x + xradius : firstTouch.x + xradius;

y座標のオフセットは初版とiOS 3.x版では、y座標を反転してから始点と終点の大きさを比較し、それに応じてオフセットを求めていました。

yOffset =(self.frame.size.height - firstTouch.y > self.frame.size.height - lastTouch.y) ?

self.frame.size.height - lastTouch.y + yradius :

self.frame.size.height - firstTouch.y + yradius;

iOS 4.x版ではy座標を反転せずに始点と終点の大きさを比較し、反転した際の値を考慮して比較値に応じてオフセットを求めています。

yOffset =(firstTouch.y < lastTouch.y) ?

self.frame.size.height - lastTouch.y + yradius :

self.frame.size.height - firstTouch.y + yradius;

初版とiOS 3.x版ではOpenGLでの座標系に変換した上で大きさを比較するなど、思考の手順そのままに計算を記述していますが、iOS 4.x版では最終的にどういう計算になるかを考慮して単純化しています。


●画像ファイルiphone.png

ファイル名は同じですが、iOS 3.x版とiOS 4.x版、更にQuartzFunとGLFunで、画像ファイルiphone.pngのサイズとアルファチャンネルの有無の違いがあります。

iOS 3.x版のGLFunプロジェクト内の画像ファイルは52 x 100ピクセルですが、よく見ると四隅がグレーになっています。

7729

背景が同一色なので気になりませんが、背景色を変えると一目瞭然です。

7732

しかし実はQuartzFunの画像ファイルにはアルファ成分が有り、四隅が透明になっています。

7730

画像ファイルを入れ替えた場合は、Xcodeの『ビルド』メニューにある『すべてのターゲットをクリーニング』で前の画像ファイルをプロジェクトから破棄して作り直す必要があります。

画像ファイルにアルファ成分がある場合、OpenGLESViewクラスのglBlendFuncによって合成が行われます。
(『GLFun(9)~OpenGLES2DViewクラス(5)』参照)

7733

コードを修正しなくても四隅が抜けるようですが、drawメソッドの初期化処理の中にglEnable(GL_BLEND)を追加して、ブレンド機能を有効化してください。

またiOS 4.x版は24 x 47ピクセルとサイズや図柄が異なるだけでなく、QuartzFunとGLFunともにアルファ成分が無いものとなっています。

7731



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 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 他

商品詳細を見る

GLFun(24)~GLFunViewクラス(3)

2012. 01. 18
10)画像の描画

        case kImageShape:
            if (sprite == nil) {
                self.sprite = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"iphone.png"]];
                glBindTexture(GL_TEXTURE_2D, sprite.name);
            }
            glEnable(GL_TEXTURE_2D);
            [sprite drawAtPoint:CGPointMake(lastTouch.x, self.frame.size.height - lastTouch.y)];
            break;

画像の描画にはTexture2Dクラスのインスタンスspriteを使用します。

spriteが存在しない場合はallocでメモリを確保し、initWithImage:メソッドでiphone.pngファイルを渡して生成します。

initWithImage:メソッドは、画像ファイルからテクスチャオブジェクトを生成します。
(initWithImage:メソッドについての詳細は『GLFun(19)~Texture2Dクラス(8)』を参照してください)

その後、glBindTextureで生成したテクスチャをバインドします。

テクスチャオブジェクトの生成とバインドが済んだら、glEnableにGL_TEXTURE_2Dを指定し、OpenGL ESサーバの二次元テクスチャリングを有効にします。

最後にdrawAtPoint:メソッドに引数として(UIKit座標系であるため、y座標を反転させた)タッチ座標を渡して呼び出し、タッチ座標を中心として画像がテクスチャリングされた矩形プリミティブを描画します。
(drawAtPoint:メソッドについての詳細は『GLFun(23)~Texture2Dクラス(12)』を参照してください)

glEnable

void glEnable(GLenum cap);

void glDisable(GLenum cap);

サーバ側のGLの機能を有効または無効にします。

glEnableとglDisableは、各種の機能を有効または無効にします。

任意の機能の現在の設定を取得するには、glIsEnabledまたはglGetを使用します。

GL_DITHERとGL_MULTISAMPLEを除き、各機能の初期値はGL_FALSEです。

GL_DITHERとGL_MULTISAMPLEの初期値はGL_TRUEです。

glEnableとglDisableの両方は、以下の値のいずれかを単一の引数capで受け取ります。

GL_ALPHA_TEST
有効にした場合、アルファテストを行います。
glAlphaFunc参照。

GL_BLEND
有効にした場合、カラーバッファ内の値で計算されたフラグメントの色の値をブレンドします。
glBlendFunc参照。

GL_COLOR_LOGIC_OP
有効にした場合、計算されたフラグメントの色とカラーバッファ値に、現在選択された論理操作を適用します。
glLogicOp参照。

GL_CLIP_PLANEi

有効にした場合、ユーザ定義のクリッピング面iに対して幾何形状をクリッピングします。

GL_COLOR_MATERIAL
有効にした場合、環境と拡散マテリアルパラメータは現在の色を追跡します。

GL_CULL_FACE
有効にした場合、ウィンドウ座標内にあるそれらのワインディングに基づいてポリゴンを間引きします。

GL_DEPTH_TEST
有効にした場合、深度の比較と深度バッファの更新を行います。
たとえ深度バッファが存在し、深度マスクが非ゼロであっても、深度テストが無効の場合は深度バッファは更新されないことに注意してください。
glDepthFuncとglDepthRange参照。

GL_DITHER
有効にした場合、カラーバッファへ書き込む前に色要素をディザリングします。

GL_FOG
有効にした場合、ポストテクスチャリングの色にフォグの色をブレンドします。
glFog参照。

GL_LIGHTi
有効にした場合、ライティング方程式の評価にライトiを含めます。
glLightModelとglLight参照。

GL_LIGHTING
有効にした場合、頂点色の計算に現在のライティングのパラメータを使用します。
それ以外の場合、単純に各頂点に現在の色を関連付けます。
glMaterial、glLightModel、そしてglLight参照。

GL_LINE_SMOOTH
有効にした場合、適切なフィルタリングでラインを描画します。
それ以外の場合、エイリアシングしたラインを描画します。
glLineWidth参照。

GL_MULTISAMPLE
有効にした場合、ピクセルの最終的な色の計算に複数のフラグメントのサンプルを使用します。
glSampleCoverage参照。

GL_NORMALIZE
有効にした場合、法線ベクトルは単位長に変換した後、ライティングの前に正規化されます。
このメソッドは、一般にGL_RESCALE_NORMALより効率的です。
glNormalとglNormalPointer参照。

GL_POINT_SMOOTH
有効にした場合、適切なフィルタリングで点を描画します。
それ以外の場合、エイリアシングした点を描画します。
glPointSize参照。

GL_POINT_SPRITE_OES

有効にした場合、ポイントスプライトが有効になります。
glPointSizeとglTexEnv参照。

GL_POLYGON_OFFSET_FILL
有効にした場合、深度の比較を実行する前にポリゴンのフラグメントの深度値にオフセットを追加します。
glPolygonOffset参照。

GL_RESCALE_NORMAL
有効にした場合、モデルビュー行列で計算された係数によって、ライティングの前に、法線ベクトルは変換後にスケーリングされます。
モデルビュー行列が空間に一律にスケーリングされる場合は、単位長に変換された法線を戻す効果があります。
このメソッドは、一般的にGL_NORMALIZEより効率的です。
glNormalとglNormalPointer参照。

GL_SAMPLE_ALPHA_TO_COVERAGE
有効にした場合、各ビットが対応するサンプル位置でのアルファ値によって決定された、一時的な適用範囲値を計算します。
一時的な適用範囲値は、フラグメントの適用範囲値とANDが取られます。

GL_SAMPLE_ALPHA_TO_ONE
有効にした場合、各サンプルのアルファ値は表現可能な最大アルファ値によって置換されます。

GL_SAMPLE_COVERAGE
有効にした場合、フラグメントの適用範囲は一時的な適用範囲値とANDが取られます。
GL_SAMPLE_COVERAGE_INVERTがGL_TRUEに設定されている場合、適用範囲値は反転されます。
glSampleCoverage参照。

GL_SCISSOR_TEST
有効にした場合、シザー矩形の外側にあるフラグメントを破棄します。
glScissor参照。

GL_STENCIL_TEST

有効にした場合、ステンシルテストを実行し、ステンシルバッファを更新します。
glStencilFunc、glStencilMask、そしてglStencilOp参照。

GL_TEXTURE_2D
有効にした場合、二次元テクスチャリングはアクティブなテクスチャユニットに対し実行されます。
glActiveTexture、glTexImage2D、glCompressedTexImage2D、そしてglCopyTexImage2D参照。

GL_CLIP_PLANEiとGL_POINT_SPRITE_OESはGLバージョン1.1以降でのみサポートされています。

capが上記にリストされた値のいずれでもない場合、GL_INVALID_ENUMが発生します。

cap:GLの機能を示すシンボリック定数を指定します。


11)レンダバッファオブジェクトのバインドと表示

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];

グラフィックスコンテキストに描画された内容をレンダバッファに出力し、ディスプレイに表示します。

まずglBindRenderbufferでレンダバッファオブジェクトをバインドします。

そしてpresentRenderbuffer:メソッドでレンダバッファのコンテンツをディスプレイに出力します。


12)deallocメソッド

- (void)dealloc {
    [currentColor release];
    [sprite release];

    [super dealloc];
}

deallocメソッドでは、retainしている2つのプロパティのcurrentColorとspriteを解放しています。


13)touchesBegan:withEvent:メソッド

タッチイベントを処理するメソッドは、基本的にQuartzFunプロジェクトのものと変わりませんが、OpenGL ESでの描画の場合はdrawメソッドの初期化処理の際にglClearで以前に描画したオブジェクトを消去しているので、再描画処理が不要になります。

touchesBegan:withEvent:メソッドでは、ビューがタッチされた時の処理を行います。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    if (useRandomColor)
        self.currentColor = [UIColor randomColor];
    UITouch *touch = [[event touchesForView:self] anyObject];
    firstTouch = [touch locationInView:self];
    lastTouch = [touch locationInView:self];
    [self draw];
}

最初にuseRandomColorでランダム色が選択されているかどうかの判別をし、ランダム色であれば描画色currentColorにランダム色を設定します。

タッチイベントの受信ですが、QuartzFunや後述するtouchesMoved:withEvent:とtouchesEnded:withEvent:では

UITouch *touch = [touches anyObject];

と単純にタッチ操作のセットを取得しているのに対し、GLFunのtouchesBegan:withEvent:メソッドだけは

UITouch *touch = [[event touchesForView:self] anyObject]

touchesForView:メソッドでビューを特定する形式に書き換えられています。

一般的には、画面が複数のビューで構成されている場合に特定のビューのみのタッチイベントを拾うためにtouchesForView:を使用するのですが、GLFunにはビューが1つしかなく、実際 [touches anyObject]と記述しても問題無く動作します。

OpenGL ESでの描画はビューそのものではなく、ビューのCAEAGLLayerに描画するためにこのような記述をしているのかもしれませんが、はっきりとした理由は分かりません。 

後は取得したタッチオブジェクトを元に、locationInView:メソッドで描画の始点firstTouchと終点lastTouchを設定し、描画メソッドdrawを呼び出しています。

touchesForView:

- (NSSet *)touchesForView:(UIView *)view

レシーバによって表されるイベント用に、特定のビューに属するタッチオブジェクトを返します。

戻り値は、レシーバによって表されるイベントに関連する、特定のビューへのタッチを表すUITouchオブジェクトのセットです。

view:イベントに関連するタッチが行われるUIViewオブジェクトを指定します。


14)touchesMoved:withEvent:メソッド

touchesMoved:withEvent:メソッドでは、ビュー内でタッチイベントが移動した時の処理を行います。

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    [self draw];
}

touchesBegan:withEvent:メソッドと異なり、単純にタッチイベントを取得し、locationInView:メソッドで描画の終点lastTouchを設定し、描画メソッドdrawを呼び出しています。


15)touchesEnded:withEvent:メソッド

touchesEnded:withEvent:メソッドでは、ビュー内でタッチが離れた時の処理を行います。

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    lastTouch = [touch locationInView:self];
    [self draw];
}

touchesMoved:withEvent:メソッドと同様に、単純にタッチイベントを取得し、locationInView:メソッドで描画の終点lastTouchを設定し、描画メソッドdrawを呼び出しています。



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 Reference Pages

UIEvent Class Reference

はじめての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 他

商品詳細を見る

GLFun(23)~Texture2Dクラス(12)

2012. 01. 17
10)drawAtPoint:メソッド

drawAtPoint:メソッドはDrawingカテゴリに属している、生成されているテクスチャオブジェクトを元に矩形プリミティブを生成しテクスチャを貼り付け、指定された点を中心に描画するメソッドです。

- (void) drawAtPoint:(CGPoint)point
{
    GLfloat coordinates[] = { 0, _maxT,
        _maxS, _maxT,
        0, 0,
        _maxS, 0 };
    GLfloat width = (GLfloat)_width * _maxS,
        height = (GLfloat)_height * _maxT;
    GLfloat vertices[] = { -width / 2 + point.x, -height / 2 + point.y, 0.0,
        width / 2 + point.x, -height / 2 + point.y, 0.0,
        -width / 2 + point.x, height / 2 + point.y, 0.0,
        width / 2 + point.x, height / 2 + point.y, 0.0 };

    glBindTexture(GL_TEXTURE_2D, _name);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

ローカル変数)

GLfloat
coordinates[ ] = { 
 0,  _maxT, 
 _maxS,  _maxT, 
 0,  0, 
 _maxS,  0 } 
テクスチャ座標配列
GLfloat width = (GLfloat)_width * _maxS 画像の幅(2の累乗
に補正していない値) 
GLfloat height = (GLfloat)_height * _maxT 画像の高さ(2の累乗
に補正していない値) 
GLfloat
vertices[ ] = {
-width / 2 + point.x,-height / 2 + point.y,0.0, 
 width / 2 + point.x,-height / 2 + point.y,0.0, 
-width / 2 + point.x, height / 2 + point.y,0.0, 
 width / 2 + point.x, height / 2 + point.y,0.0}
頂点座標配列

・widthとheightについて

drawAtPoint:メソッドは、initWithImage:を呼び出して画像データを設定した後に呼び出します。

initWithImage:内では、最後の方でinitWithData:pixelFormat:pixelsWide:pixelsHigh:contentSize:を呼び出してテクスチャオブジェクトを設定していますが、この際サイズなどの変数の設定も行っています。
(『GLFun(16)~Texture2Dクラス(5)』参照)

したがって、ここでの_witdhと_heightは2の累乗補正をした幅と高さ、_maxSと_maxTはそれぞれ((元のサイズ) / (2の累乗補正サイズ))の比になりますので、widthとheightは元の幅と高さということになります。

・テクスチャ座標

テクスチャ座標系は左上角を原点としていますので、テクスチャ座標配列coordinatesは下図のような形になります。

元画像サイズと2の累乗補正をしたサイズとの比を指定することで、余白部分を除いた画像データの部分のみを貼り付けることができます。

(C') (D')
 
(0, 0)   (_maxS, 0)
     
(0, _maxT)   (_maxS, _maxT)
 → S
(A')

(B')

・頂点座標

頂点座標系はxとyが正の場合に左下角を原点としていますので、頂点座標配列verticesは下図のような形になります。

引数pointの座標が中心になるように、元画像サイズを半分にした値をpointに加減算して頂点座標を設定しています。

(C)Y
↑ 
 
(D)
 
(-width / 2 + point.x,
height / 2 + point.y)
   (width / 2 + point.x,
height / 2 + point.y)
  (point.x, point.y)  
(-width / 2 + point.x,
-height / 2 + point.y)
   (width /2 + point.x,
-height / 2 + point.y)
  → X
(A)(B)

テクスチャのバインド)

glBindTextureでテクスチャを貼るターゲットへ名付けられたテクスチャ_nameをバインドします。

頂点座標配列の指定)

glVertexPointerでレンダリング時に使用する頂点座標の配列の位置とデータを指定します。

第一引数は各頂点の座標数で、ここではx、y、zで構成されているので3になります。

第二引数は頂点座標のデータ型で、GL_FLOATになります。

第三引数は頂点間のバイトオフセットで、0を指定します。

第四引数は頂点座標配列へのポインタで、配列verticesを指定します。

テクスチャ座標配列の指定)

glTexCoordPointerでレンダリング時に使用するテクスチャ座標の配列の位置とデータを指定します。

第一引数は配列要素ごとの座標数で、ここでは2Dテクスチャなので2になります。

第二引数はテクスチャ座標のデータ型で、GL_FLOATになります。

第三引数は配列要素間のバイトオフセットで、0を指定します。

第四引数は配列内の最初の座標へのポインタで、ここでは最初の要素なのでcoordinatesを指定します。

glTexCoordPointer

void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer);

glTexCoordPointerはレンダリング時に使用するテクスチャ座標の配列の位置とデータを指定します。

sizeは要素ごとの座標数を指定し、2、3、または4である必要があります。

typeは各テクスチャ座標のデータ型を指定し、strideはある配列要素から次に与える頂点へのバイトストライドと、単一の配列または別々の配列内に格納する属性を指定します。
(単一の配列のストレージは、いくつかの実装でより効率的な場合があります。)

テクスチャ座標配列が指定されている場合、sizetypestride、そしてpointerはクライアント側の状態として保存されます。

テクスチャ座標配列が有効な場合、glDrawArraysまたはglDrawElementsが呼び出された時に使用されます。

クライアント側のアクティブなテクスチャユニットのテクスチャ座標配列を有効または無効にするには、引数GL_TEXTURE_COORD_ARRAYでglEnableClientStateまたはglDisableClientStateを呼び出します。

全てのクライアント側のアクティブなテクスチャユニットのテクスチャ座標配列の初期状態は無効で、glDrawArraysまたはglDrawElementsが呼び出された時にアクセスできません。

予め指定された頂点と頂点属性配列から(全て同じ型の)プリミティブのシーケンスを構築するにはglDrawArraysを使用してください。

インデックス化された頂点と頂点属性によってプリミティブのシーケンスを構築するにはglDrawElementsを使用してください。

glTexCoordPointerは、通常クライアント側に実装されています。

glTexCoordPointerはglClientActiveTextureを指定して、クライアント側のアクティブなテクスチャユニットのテクスチャ座標配列を更新します。

sizeが2、3、または4でない場合、GL_INVALID_VALUEが発生します。

typeが有効な値でない場合、GL_INVALID_ENUMが発生します。

strideが負の場合、GL_INVALID_VALUEが発生します。

size:配列要素ごとの座標数を指定します。
2、3、または4である必要があります。
初期値は4です。

type:各テクスチャ座標のデータ型を指定します。
シンボリック定数GL_BYTE、GL_SHORT、そしてGL_FIXEDが有効です。
ただし初期値はGL_FLOATです。
一般的なプロファイルでは、シンボリック定数GL_FLOATも有効です。

stride:連続した配列要素間のバイトオフセットを指定します。
strideが0の場合、配列要素は隙間無く格納されていると解釈されます。
初期値は0です。

pointer:配列内の最初の要素の最初の座標へのポインタを指定します。
初期値は0です。

配列データのレンダリング)

glDrawArraysで配列データからプリミティブをレンダリングします。

第一引数はプリミティブで、4個の頂点から矩形を生成するGL_TRIANGLE_STRIPを指定します。

第二引数は配列内の開始インデックスで、ここでは最初の要素なので0を指定します。

第三引数はレンダリングするインデックス数で、矩形ですから4を指定します。

レンダリング結果)

プリミティブは、ローカル変数の頂点座標の図でいうと三角形(A)-(B)-(C)と(B)-(C)-(D)が繋がった矩形を形成します。

この矩形(A)-(B)-(C)-(D)に対し、テクスチャ(A')-(B')-(C')-(D')はその配列順序に対応して関連付けられて貼られることになります。

したがって、テクスチャ座標配列を(B')-(A')-(D')-(C')とすると左右反転、(C')-(D')-(A')-(B')とすると上下反転したテクスチャが貼られます。

左右反転:(B')-(A')-(D')-(C')
7726

上下反転:(C')-(D')-(A')-(B')
7727

11)drawInRect:メソッド

drawInRect:メソッドはDrawingカテゴリに属している、指定された矩形に生成されているテクスチャを貼り付けて描画するメソッドです。

- (void) drawInRect:(CGRect)rect
{
    GLfloat coordinates[] = { 0, _maxT,
        _maxS, _maxT,
        0, 0,
        _maxS, 0 };

    GLfloat vertices[] = { rect.origin.x, rect.origin.y, 0.0,
        rect.origin.x + rect.size.width, rect.origin.y, 0.0,
        rect.origin.x, rect.origin.y + rect.size.height, 0.0,
        rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, 0.0 };

    glBindTexture(GL_TEXTURE_2D, _name);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

ローカル変数)

GLfloat
coordinates[ ] = { 
 0,  _maxT, 
 _maxS,  _maxT, 
 0,  0, 
 _maxS,  0 } 
GLfloat
vertices[ ] = {
rect.origin.x,rect.origin.y,0.0,
rect.origin.x + rect.size.width,rect.origin.y,0.0,
rect.origin.x,rect.origin.y + rect.size.height,0.0,
rect.origin.x + rect.size.width,rect.origin.y + rect.size.height,0.0 }

・テクスチャ座標

テクスチャ座標系は先のdrawAtPointと同じで、左上角を原点としていますので、テクスチャ座標配列coordinatesは下図のような形になります。

元画像サイズと2の累乗補正をしたサイズとの比を指定することで、余白部分を除いた画像データの部分のみを貼り付けることができます。

(C') (D')
 
(0, 0)   (_maxS, 0)
     
(0, _maxT)   (_maxS, _maxT)
  → S
(A')

(B')

・頂点座標

頂点座標系はxとyが正の場合に左下角を原点としていますので、頂点座標配列verticesは下図のような形になります。

引数rectで渡されている原点座標originとサイズsizeを元に頂点座標を設定しています。

(C)Y
↑ 
 
(D)
 
(rect.origin.x,
rect.origin.y + rect.size.height)
   (rect.origin.x + rect.size.width,
rect.origin.y + rect.size.height)
     
(rect.origin.x,
rect.origin.y)
   (rect.origin.x + rect.size.width,
rect.origin.y)
  → X
(A)(B)

テクスチャのバインド)

glBindTextureでテクスチャを貼るターゲットへ名付けられたテクスチャ_nameをバインドします。

頂点座標配列の指定)

glVertexPointerでレンダリング時に使用する頂点座標の配列の位置とデータを指定します。

第一引数は各頂点の座標数で、ここではx、y、zで構成されているので3になります。

第二引数は頂点座標のデータ型で、GL_FLOATになります。

第三引数は頂点間のバイトオフセットで、0を指定します。

第四引数は頂点座標配列へのポインタで、配列verticesを指定します。

テクスチャ座標配列の指定)

glTexCoordPointerでレンダリング時に使用するテクスチャ座標の配列の位置とデータを指定します。

第一引数は配列要素ごとの座標数で、ここでは2Dテクスチャなので2になります。

第二引数はテクスチャ座標のデータ型で、GL_FLOATになります。

第三引数は配列要素間のバイトオフセットで、0を指定します。

第四引数は配列内の最初の座標へのポインタで、ここでは最初の要素なのでcoordinatesを指定します。

配列データのレンダリング)

glDrawArraysで配列データからプリミティブをレンダリングします。

第一引数はプリミティブで、4個の頂点から矩形を生成するGL_TRIANGLE_STRIPを指定します。

第二引数は配列内の開始インデックスで、ここでは最初の要素なので0を指定します。

第三引数はレンダリングするインデックス数で、矩形ですから4を指定します。

レンダリング結果)

GLFunViewクラスのdrawメソッドで、セグメンテッドコントロールでImageを選択した場合の実装は後で解説するのですが、画像ファイルを描画するdrawAtPoint:の代わりにdrawInRect:メソッドを呼び出す場合の注意点を紹介します。

[sprite drawInRect:CGRectMake(lastTouch.x, self.frame.size.height - lastTouch.y, 200.0, 200.0)];

原点座標にタッチされた座標(y座標はUIKit座標系に対して反転)を、サイズは200×200ピクセルを設定した場合は下図のようになります。

7728

drawAtPoint:はタッチ座標を中心にプリミティブが作られますが、drawInRect:はタッチ座標を左下角の原点として描画されます。

タッチ座標を中心に描画する場合は、サイズを半分にして原点に対して加減算する頂点座標配列を設定してください。



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 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 他

商品詳細を見る

GLFun(22)~Texture2Dクラス(11)

2012. 01. 16
9)initWithString:dimensions:alignment:fontName:fontSize:メソッド

initWithString:dimensions:alignment:fontName:fontSize:メソッドはTextカテゴリに属している、指定した文字列と矩形領域、フォントから画像データを生成し、initWithData:pixelFormat:pixelsWide:pixelsHigh:contentSize:メソッドを呼び出してテクスチャオブジェクトを作成するメソッドです。

- (id) initWithString:(NSString*)string dimensions:(CGSize)dimensions alignment:(UITextAlignment)alignment fontName:(NSString*)name fontSize:(CGFloat)size
{
    NSUInteger width,
        height,
        i;
    CGContextRef context;
    void* data;
    CGColorSpaceRef colorSpace;
    UIFont * font;

    font = [UIFont fontWithName:name size:size];

    width = dimensions.width;
    if((width != 1) && (width & (width - 1))) {
        i = 1;
        while(i < width)
        i *= 2;
        width = i;
    }
    height = dimensions.height;
    if((height != 1) && (height & (height - 1))) {
        i = 1;
        while(i < height)
        i *= 2;
        height = i;
    }

    colorSpace = CGColorSpaceCreateDeviceGray();
    data = calloc(height, width);
    context = CGBitmapContextCreate(data, width, height, 8, width, colorSpace, kCGImageAlphaNone);
    CGColorSpaceRelease(colorSpace);

    CGContextSetGrayFillColor(context, 1.0, 1.0);
    CGContextTranslateCTM(context, 0.0, height);
    CGContextScaleCTM(context, 1.0, -1.0);    //NOTE: NSString draws in UIKit referential i.e. renders upside-down compared to CGBitmapContext referential
    UIGraphicsPushContext(context);
        [string drawInRect:CGRectMake(0, 0, dimensions.width, dimensions.height) withFont:font lineBreakMode:UILineBreakModeWordWrap alignment:alignment];
    UIGraphicsPopContext();

    self = [self initWithData:data pixelFormat:kTexture2DPixelFormat_A8 pixelsWide:width pixelsHigh:height contentSize:dimensions];

    CGContextRelease(context);
    free(data);

    return self;
}

ローカル変数)

 NSUInteger  width 画像の幅(2の累乗に補正した値)
 height 画像の高さ(2の累乗に補正した値)
 i whileループで使用するカウンタ用の変数
 CGContextRef  context 画像処理を行うためのグラフィックスコンテキスト
 void*  data テクスチャ用画像データを保持するメモリ領域
 CGColorSpaceRef  colorSpace 色空間情報
 UIFont *  font フォントオブジェクト

フォントオブジェクトの生成)

引数として受け取ったフォント名name(プロパティのnameとは別物)とフォントサイズsizeから、fontWithName:size:メソッドでフォントオブジェクトを生成します。

テクスチャ用サイズへの補正)

initWithImage:と同様にテクスチャ用の画像サイズとして、引数として受け取ったサイズdimensionsから2の累乗に補正した幅widthと高さheightを設定します。
(『GLFun(20)~Texture2Dクラス(9)』参照)

条件はほぼ同じですがwhileループの条件でsizeToFitによる制限をかけていないので、設定される大きさは元サイズを超える最小の2の累乗になります。

ビットマップグラフィックスコンテキストの生成)

このメソッドで生成する文字列のテクスチャは白色不透明の文字のため、色空間はグレースケール、色成分も各ピクセル8ビット分だけ確保することになります。

最初にCGColorSpaceCreateDeviceGrayでデバイス依存のグレースケール色空間を生成します。

次に画像データを保持するdataのメモリを、callocで高さ×幅×1バイト(8ビット)分確保します。
(『初心者のためのポイント学習C言語/ライブラリ関数一覧/calloc』参照)

続いてCGBitmapContextCreate』でビットマップグラフィックスコンテキストを生成します。

色空間がグレースケールなのでinitWithImage:のkTexture2DPixelFormat_A8の場合とほぼ同じで、第七引数がアルファチャンネル無しのkCGImageAlphaNoneになる点だけが異なります。

コンテキストの生成が済んだら、不要になった色空間をCGColorSpaceReleaseで解放します。

CGColorSpaceCreateDeviceGray

CGColorSpaceRef CGColorSpaceCreateDeviceGray(
    void
);

デバイス依存のグレースケール色空間を生成します。

戻り値はデバイス依存のグレースケール色空間です。

このオブジェクトは、CGColorSpaceReleaseを呼び出すことによって解放する責任があります。

失敗した場合はNULLを返します。

Mac OS X v10.4以降では、この色空間はもはやデバイスに依存せず、『色空間名』で説明されている汎用的なもの(kCGColorSpaceGenericGray)に置換されています。

Mac OS X v10.4以降でこの関数を使用する場合、色は汎用的な色空間にマッピングされます。

カラーマッチングをバイパスする場合は、対象となるコンテキストの色空間を使用してください。

デバイスでの色は、出力デバイス上で表示する時に依存している色空間への変換、ないしは他の方法での変更はされず、色の視覚的な外観を保持しようとはしません。

したがって、デバイスの色空間の色は異なる出力デバイス上で表示する時に、しばしば異なって表示されます。

この理由から、デバイス色空間は色の保存が重要な場合には推奨されません。

フォント色の設定)

文字列の色はコンテキストの塗りつぶし色としてCGContextSetGrayFillColor』で設定します。

第一引数は設定するコンテキストを指定します。

第二引数はグレーレベルで、黒の0.0から白の1.0までの値を指定します。

第三引数は不透明度のレベルで、透明の0.0から不透明の1.0までの値を指定します。

ここでは第二、第三引数とも1.0なので、フォント色は不透明な白色となります。

CGContextSetGrayFillColor

void CGContextSetGrayFillColor (
    CGContextRef c,
    CGFloat gray,
    CGFloat alpha
);

DeviceGray色空間内の値に現在の塗りつぶし色を設定します。

この関数を呼び出すと2つのことが起こります。

・QuartzはDeviceGrayに現在の塗りつぶし色空間を設定します。
・Quartzはグレーとアルファパラメータで指定した値に現在の塗りつぶし色を設定します。

c:現在の塗りつぶし色を設定するグラフィックスコンテキストを指定します。

gray:希望するグレーレベルを指定する値を指定します。
DeviceGray色空間は0.0(完全な黒)から1.0(完全な白)までの範囲の値の指定を許可します。

alpha:不透明度レベルの値を指定します。
値は0.0(透明)から1.0(不透明)までの範囲で指定できます。
範囲外の値は0.0または1.0にクリッピングされます。

コンテキスト内でのユーザ座標系の原点の変更)

コードの中で、『NSStringのUIKitに関連する描画、すなわちレンダリングは『CGBitmapContext』関連と比較して逆さまになります。』という注意書きがあります。

詳細は後述しますがコンテキストに文字列を描画するメソッドdrawInRect:withFont:lineBreakMode:alignment:はUIKitのメソッドなため、左上角を原点とするUIKit座標系で描画されます。

したがって左下角を原点とするCore Graphics座標系に戻した際には、x軸を中心に反転した画像になるためCGContextScaleCTMでy座標の反転を行います。

また(コードの記述順と前後しますが)、それによってy座標が負の値になるので、CGContextTranslateCTMで原点を画像の高さheight分移動させます。

CGContextScaleCTM

void CGContextScaleCTM (
    CGContextRef c,
    CGFloat sx,
    CGFloat sy
);

コンテキスト内のユーザ座標系のスケールを変更します。

c:グラフィックスコンテキストを指定します。

sx:指定されたコンテキストの座標空間のx軸をスケールする係数を指定します。

sy:指定されたコンテキストの座標空間のy軸をスケールする係数を指定します。

コンテキストへの文字列の描画)

前述の通り文字列の描画はUIKit上で行うためグラフィックスコンテキストを切り替える必要があります。

まずUIGraphicsPushContext』で、Core Graphicsのビットマップグラフィックスコンテキストで現在のコンテキストを作成します。

次にdrawInRect:withFont:lineBreakMode:alignment:で文字列を描画します。

第一引数は描画する境界矩形で、原点を(0, 0)に、サイズは元サイズとなるdimensions構造体の幅と高さを指定します。

第二引数は文字列の描画に使用するフォントで、呼び出し時の引数が渡されます。

第三引数は文字列の改行オプションで、ここでは単語の境界で折り返すUILineBreakModeWordWrapが指定されています。

第四引数は領域内での文字列の揃え方で、呼び出し時の引数が渡されます。

文字列の描画を終えたら、UIGraphicsPopContextで現在のコンテキストを破棄し、元のコンテキストに戻ります。

UIGraphicsPushContext

void UIGraphicsPushContext (
    CGContextRef context
);

指定したグラフィックスコンテキストで現在のコンテキストを作成します。

この関数は、以前のグラフィックスの状態を保存したり、指定したコンテキストで現在のコンテキストの作成に使用することができます。

この関数は、UIGraphicsPopContext関数の呼び出しと対にしてバランスを取る必要があります。

context:現在のコンテキストを作成するグラフィックスコンテキストを指定します。

drawInRect:withFont:lineBreakMode:alignment:

- (CGSize)drawInRect:(CGRect)rect withFont:(UIFont *)font lineBreakMode:(UILineBreakMode)lineBreakMode alignment:(UITextAlignment)alignment

指定された境界矩形、フォントそして属性を使用して、現在のグラフィックスコンテキスト内に文字列を描画します。

戻り値はレンダリングされた文字列の実際のサイズです。

rect:文字列を描画する(現在のグラフィックスコンテキストの)境界矩形を指定します。

font:レンダリングに使用するフォントを指定します。

lineBreakMode:文字列のサイズを計算するための改行オプションを指定します。
有効な値は『UILineBreakMode』を参照してください。

alignment:境界矩形内のテキストの揃え方を指定します。
有効な値は『UITextAlignment』を参照してください。

UILineBreakMode

テキストの折り返しと切り詰めのオプションです。

typedef enum {
    UILineBreakModeWordWrap = 0,
    UILineBreakModeCharacterWrap,
    UILineBreakModeClip,
    UILineBreakModeHeadTruncation,
    UILineBreakModeTailTruncation,
    UILineBreakModeMiddleTruncation,
UILineBreakMode;

UILineBreakModeWordWrap
単語の境界でのみ、折り返しまたは切り取りを行います。
これはデフォルトの折り返しオプションです。

UILineBreakModeCharacterWrap
最も近い文字の境界で、文字列の折り返しまたは切り取ります。

UILineBreakModeClip
描画矩形の終端に到達した時にテキストを切り取ります。
このオプションは文字列の終端で文字が部分的にレンダリングされる可能性があります。

UILineBreakModeHeadTruncation
行頭から(必要に応じて)テキストを切り詰めます。
複数行のテキストの場合は、最初の行のテキストのみが切り詰められます。

UILineBreakModeTailTruncation
行末から(必要に応じて)テキストを切り詰めます。
複数行のテキストの場合は、最後の行のテキストのみが切り詰められます。

UILineBreakModeMiddleTruncation
行の中央から(必要に応じて)テキストを切り詰めます。
複数行のテキストの場合は、行の中央のテキストのみが切り詰められます。

(矩形領域内で描画する)指定されたポイントで描画するための方法に対し、これらのオプションは文字列に適用される切り取り動作を指定します。

UIGraphicsPopContext

void UIGraphicsPopContext (
    void
);

スタックの先頭から現在のグラフィックスコンテキストを削除して、以前のコンテキストを復元します。

この関数はUIGraphicsPushContext関数の呼び出しとのバランスを取るために使用されます。

この関数は、アプリケーションのメインスレッドからのみ呼び出す必要があります。

テクスチャオブジェクトの作成)

作成した文字列からの画像データを元に、initWithData:pixelFormat:pixelsWide:pixelsHigh:contentSize:を呼び出してテクスチャオブジェクトを生成、バインド、設定します。
(同メソッドについては『GLFun(16)~Texture2Dクラス(5)』を参照してください)

ピクセルフォーマットはkTexture2DPixelFormat_A8を指定します。

コンテキストと画像データの解放)

不要となったコンテキストはCGContextReleaseで、画像データはfreeで解放します。

実行について)

GLFunViewクラスのdrawメソッドで、セグメンテッドコントロールでImageを選択した場合の実装は後で解説するのですが、画像ファイルを描画するinitWithImage:の代わりにinitWithString:dimensions:alignment:fontName:fontSize:メソッドを呼び出す場合の注意点を紹介します。

Texture2Dオブジェクトspriteを次のように設定します。

self.sprite = [[Texture2D alloc] initWithString:@"\アッカリ~ン/" dimensions:CGSizeMake(220.0, 40.0) alignment:UITextAlignmentCenter fontName:@"Hiragino Kaku Gothic ProN" fontSize:36.0];

文字列を『\アッカリ~ン/』、表示領域を220×40ピクセル、文字揃えはUITextAlignmentCenterで中央揃えに、フォントはヒラギノ角ゴシックの36ポイントを指定して実行すると下記のようになります。

7724

赤はデフォルトの選択色で、選択色を変えればその色になります。

しかし画像データはグレースケールで作りましたから色が付くことはないはずで、そもそも文字が表示されません。

これはinitWithData:pixelFormat:pixelsWide:pixelsHigh:contentSize:メソッド(『GLFun(16)~Texture2Dクラス(5)』参照)のkTexture2DPixelFormat_A8の場合、glTexImage2Dでテクスチャの色要素およびピクセルデータのフォーマットをアルファ成分であるGL_ALPHAに設定しているため、色成分と認識されず正常に表示できないようです。

そこでGL_ALPHAから輝度値を示すGL_LUMINANCEに変更します。

glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);

7725

すると正常に文字列が表示されるようになります。

GLFunでは文字列テクスチャの使用を想定していないので対応していないのは仕方ありませんが、アルファ成分のみの画像と併用するのであればTexture2DPixelFormatの定数に輝度用の値を追加して上記のように設定すると良いかもしれません。



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 Reference Pages

CGColorSpace Reference

CGContext Reference

UIKit Function Reference

NSString UIKit Additions Reference

初心者のためのポイント学習C言語/ライブラリ関数一覧/calloc

はじめての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 他

商品詳細を見る

GLFun(21)~Texture2Dクラス(10)

2012. 01. 15
未適用アフィン変換のチェックと適用)

GLFun(20)~Texture2Dクラス(9)』で述べたように、テクスチャ用画像のサイズが最大テクスチャサイズを超えていた場合にはアフィン変換で補正処理を行いますので、アフィン変換を適用する必要があります。

未適用のアフィン変換があるかどうかをCGAffineTransformIsIdentityで確認し、あればCGContextConcatCTMで適用します。

CGContextConcatCTM

void CGContextConcatCTM (
    CGContextRef c,
    CGAffineTransform transform
);

コンテキスト内のユーザ座標系を、指定した行列を使用して変換します。

関数CGContextConcatCTMを呼び出すと、2つの行列を乗算によって連結(つまり結合)します。

行列を連結する順序は、演算が可換ではないため重要です。

CGContextConcatCTMを呼び出すと、コンテキスト内のCTMの結果は次のようになります。

CTMnew = transform * CTMcontext

c:グラフィックスコンテキストを指定します。

transform:指定されたコンテキストの現在の変換行列に適用する変換行列を指定します。

コンテキストへの画像の描画)

CGContextDrawImageを使用して、ビットマップグラフィックスコンテキストにテクスチャ用画像を描画します。

第一引数は画像を描画するコンテキストcontextを指定します。

第二引数は画像を描画する領域で、CGRectMakeで原点とサイズを指定します。

サイズはCGImageGetWidthCGImageGetHeightで元画像imageから取得します。

第三引数は描画する画像imageを指定します。

この時点でのコンテキストの状態は、左下角を原点とするCore Graphics座標系で、透明にクリアされた(2の累乗補正された)width×heightの領域内に、元画像を元サイズのまま描画していることになっています。

7721

CGContextDrawImage

void CGContextDrawImage (
    CGContextRef c,
    CGRect rect,
    CGImageRef image
);

グラフィックスコンテキストに画像を描画します。

Quartzは、画像が不均衡であれば必要に応じてrectパラメータで指定された境界に適合するように伸縮します。

c:画像を描画するグラフィックスコンテキストを指定します。

rect:画像を描画するための境界ボックスのユーザ空間での位置と大きさを指定します。

image:描画する画像を指定します。

RGBA8888からRGB565へのビットマップデータの変換)

アルファチャンネル無しのビットマップデータは、内部的にはピクセル単位で『RRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA』という各色8ビットずつの32ビットデータ(RGBA8888)ですので、これを本来の『RRRRRGGGGGGBBBBB』という16ビットデータ(RGB565)に変換する必要があります。
(ソースコードのコメント文のRGBA8888の表現ではRが9個あったりしますが、正しくは8個です)

この変換は、ビットマップデータを格納しているメモリ領域dataから32ビットずつデータを取り出し、各色に対してビットマスクで抽出、ビットシフトで長さを切り詰め、論理和で合成して一時メモリ領域tempDataに埋めて、最後にtempDataの内容をdataに入れ替えるという作業になります。

最初に一時メモリ領域tempDataをmallocで、(2の累乗補正した)高さ×幅×2バイト(16ビット)分を確保します。

次に元となる画像データの領域dataから32ビットずつピクセルデータを取り出すためのポインタinPixel32と、一時メモリ領域tempDataに16ビットずつピクセルデータを書き出すためのポインタoutPixel16を設定します。

続いてforループで(width * height)個あるピクセルデータを一つずつ(32ビットずつ)取り出し、ビットシフト演算でRGBA8888の32ビットからRGB565の16ビットへ変換します。

まず(*inPixel32 >> 0)で、データの頭出しを行います。
(Rの場合は先頭アドレスなのでずらす必要が無く、0を指定しています)

そしてRの8ビット分を抽出するため、ビットマスク0xFFでビット論理積を取ります。

抽出したRの8ビットデータを5ビットに切り詰めるため、右ビットシフトで3つずらします。

5ビットにしたRデータは、後で16ビットのデータに論理和で合成するため、左ビットシフトで11個ずらします。

GとBについても同様にビット操作を行い、RGBを論理和で合成して、16ビットデータをoutPixel16に順次入れていきます。

ビット操作に関しては下図を参照してください。

7711

これによりRGBA8888の場合は各色8ビット(0~255)であった色分解能から、RとBは5ビット(0~32)の1/8に、Gは6ビット(0~64)の1/4の色分解能に低下します。

全てのピクセルに対して変換が完了したら元画像データのメモリdataを一度解放し、一時メモリtempDataの内容をdataに入れ直します。

テクスチャオブジェクトの作成)

画像データが完成したので、initWithData:pixelFormat:pixelsWide:pixelsHigh:contentSize:を呼び出してテクスチャオブジェクトを生成、バインド、設定します。
(同メソッドについては『GLFun(16)~Texture2Dクラス(5)』を参照してください)

コンテキストと画像データの解放)

テクスチャオブジェクトの作成が完了したので、不要となったコンテキストはCGContextReleaseで、画像データはfreeで解放します。

CGContextRelease

void CGContextRelease (
    CGContextRef c
);

グラフィックスコンテキストの保持カウントを減らします。

この関数はCFReleaseと同等で、cがNULLの場合以外ではエラーは発生しません。

c:解放するグラフィックスコンテキストを指定します。



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 Reference Pages

CGContext Reference

はじめての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 他

商品詳細を見る

GLFun(20)~Texture2Dクラス(9)

2012. 01. 14
テクスチャ用サイズへの補正)

元画像サイズを設定したimageSize構造体から、テクスチャ用に2の累乗にサイズを補正し、widthとheightとして設定します。

widthとheightは共に全く同じ演算をしていますので、widthを例に説明します。

まずimageSize構造体のwidthメンバの値を、補正した幅を設定するwidthに設定します。

次にwidthが2の累乗かどうかを、条件『(width != 1) && (width & (width - 1))』で判別します。

2の累乗は2進数で表すと桁が繰り上がった状態であり、その値から1を減算した値とのビット論理積は0(偽)になる性質があります。

2の累乗 = n10進数2進数n - 1n & (n - 1)
201000000010000000000000000
212000000100000000100000000
224000001000000001100000000
238000010000000011100000000
2416000100000000111100000000
2532001000000001111100000000
2664010000000011111100000000
27128100000000111111100000000

したがって条件からすれば (width & (width - 1))だけで済み、(width != 1)で1を除外して論理積を演算する意味が無く、理由が分かりません。

widthが符号無し整数であるため、(width - 1)の演算を回避するために(width != 0)で0を除外するという話なら分かりますが、0は除外されずにそのまま計算されます。

『width & ~』の時点で0の論理積は自動的に偽になるため、負の値になる(width - 1)は計算されないのかもしれません。

単に私が気付いていない理由があるかもしれないので、条件はそのままにしておきます。

さてwidthが2の累乗でない場合は、カウンタiを1としてwhileループで2の累乗になる幅を決定します。

whileループの条件は、ブール値sizeToFitが真ならiを2倍に、偽ならiはそのままとし、iをwidthと比較しています。

widthより小さい間はiを2倍にして、widthを超えたらiをwidthに設定します。

フラグsizeToFitは予めNOに設定されているため、常にiとwidthを比較することになり、iはwidthより大きくなります。

仮にsizeToFitがYESの場合、iはwidthと比較する前に2倍にされるので、iはwidthより小さくなります。

つまりsizeToFitは、YESの場合は元画像の幅より小さい最大の2の累乗に収めるためのフラグで、NOの場合は元画像の幅を超える最小の2の累乗を求めていることになります。

今回のGLFunプロジェクトの場合、使用する元画像iphone.pngのサイズは52×100ピクセルですが、2の累乗補正を行うとwidth = 64、height = 128となります。

最大テクスチャサイズを超える場合の補正)

iOS OpenGL ESプログラミングガイド』の『PowerVR MBX上のOpenGL ES 1.1』で示されているように、最大テクスチャサイズは1024×1024に制限されていますが、元画像サイズが1024を超える場合の処理も実装されています。

widthとheightどちらかが1024より上の場合は、whileループでどちらとも1024以下になるまで、テクスチャ用に2の累乗補正をしたwidthとheightだけでなく、元画像サイズのimageSize構造体の値、さらにCGコンテキストにそのことを伝えるためにCGAffineTransformScaleでアフィン変換も含めて全て1/2に変換します。

したがって、これまでimageSize構造体の値は元画像サイズと説明してきましたが、厳密に言えば幅ないし高さが1024ピクセルを超えていた場合には、縮小補正されたサイズになることに注意してください。

ビットマップグラフィックスコンテキストの生成)

ピクセルフォーマットに応じてビットマップグラフィックスコンテキストを生成します。

kTexture2DPixelFormat_RGBA8888の場合)

色空間が存在し、アルファチャンネルが存在する場合です。

まずCGColorSpaceCreateDeviceRGBでデバイス依存のRGB色空間を生成します。

次に画像データを保持するdataのメモリを、mallocで高さ×幅×4バイト(32ビット)分確保します。

変数dataをvoid型にしているのは、ピクセルフォーマットによって確保するメモリ量が変わるので型を指定したくないためです。
(『碧色工房-blue studio-/C言語/ポインタとメモリと型(構造体)の関係 (3)』参照)

続いてCGBitmapContextCreateでビットマップグラフィックスコンテキストを生成します。

第一引数はテクスチャ画像をレンダリングするメモリの転送先、つまり先程確保したdataへのポインタになります。

第二、第三引数はビットマップの幅と高さで、テクスチャ用に2の累乗で補正したwidthとheightを指定します。

第四引数はピクセルの各色成分を表すビット数ですので、8を指定します。

第五引数は行毎に使用するメモリのバイト数で、RGBA用に4バイト×widthを指定します。

第六引数は色空間なので、先程取得した色空間colorSpaceを指定します。

第七引数はアルファチャンネルの情報で、kCGImageAlphaPremultipliedLastはアルファが最下位ビットに格納されていて事前にアルファを乗算済、kCGBitmapByteOrder32Bigは32ビットのビッグエンディアンフォーマットを示しており、2つの論理和を指定しています。

コンテキストの設定が済んだら、CGColorSpaceReleaseで色空間の保持カウントを減らす、すなわち色空間の解放を行います。

kTexture2DPixelFormat_RGB565の場合)

色空間が存在しアルファチャンネルが存在しない場合ですので、RGBA8888と同じく色空間の生成、メモリの確保を行います。

色成分がRGB565の16ビットであるのにメモリを32ビット分確保しているのは、RGBA8888とRGB565の判別はアルファチャンネル情報の有無でしか見ていないためで、実際には16ビットカラーでないからです。

したがってこの段階では32ビット分確保した画像データを作成し、後で別途16ビットRGB565カラーへとデータの変換を行います。

コンテキストの生成での差異は、CGBitmapContextCreateの第七引数でアルファチャンネルが無しで最下位ビットを無視するkCGImageAlphaNoneSkipLastに変更されている点です。
(32ビットのビッグエンディアンフォーマットを示すkCGBitmapByteOrder32Bigは変更無し)

kTexture2DPixelFormat_A8の場合)

色空間が存在しない場合ですので、色空間を取得する必要が無く、確保するメモリも高さ×幅(×1バイト)となります。

コンテキストの生成も条件を加味し、第五引数の行毎のメモリのバイト数はwidth分のみ、第六匹数の色空間の指定はNULL、第七引数のアルファチャンネル情報はアルファチャンネルのみを示すkCGImageAlphaOnlyに修正します。
(各ピクセル1バイトの情報なので、バイトオーダーを示すImage Bitmap Information定数は不要)

デフォルト)

デフォルトは3種のピクセルフォーマット以外の場合(コードの記述上はいずれかになるはずなので、何らかの異常が発生した場合)は、raise:format:メソッドで例外を発生させます。

例外のメッセージはNSInternalInconsistencyExceptionで、コード内で予期しない状態が起こったことを示します。

CGColorSpaceCreateDeviceRGB

CGColorSpaceRef CGColorSpaceCreateDeviceRGB(
    void
);

デバイス依存のRGB色空間を生成します。

戻り値はデバイス依存のRGB色空間です。

このオブジェクトは、CGColorSpaceReleaseを呼び出すことによって解放する責任があります。

失敗した場合はNULLを返します。

Mac OS X v10.4以降では、この色空間はもはやデバイスに依存せず、『色空間名』で説明されている汎用的なもの(kCGColorSpaceGenericRGB)に置換されています。

Mac OS X v10.4以降でこの関数を使用する場合、色は汎用的な色空間にマッピングされます。

カラーマッチングをバイパスする場合は、対象となるコンテキストの色空間を使用してください。

デバイスでの色は、出力デバイス上で表示する時に依存している色空間への変換、ないしは他の方法での変更はされず、色の視覚的な外観を保持しようとはしません。

したがって、デバイスの色空間の色は異なる出力デバイス上で表示する時に、しばしば異なって表示されます。

この理由から、デバイス色空間は色の保存が重要な場合には推奨されません。

CGBitmapContextCreate

CGContextRef CGBitmapContextCreate (
    void *data,
    size_t width,
    size_t height,
    size_t bitsPerComponent,
    size_t bytesPerRow,
    CGColorSpaceRef colorspace,
    CGBitmapInfo bitmapInfo
);

ビットマップグラフィックスコンテキストを生成します。

戻り値は新しいビットマップコンテキスト、あるいはコンテキストが生成できなかった場合はNULLを返します。

このオブジェクトはCGContextReleaseを使用して解放する責任があります。

この関数を呼び出すと、Quartzは指定したビットマップを描画する環境(つまりビットマップコンテキスト)を生成します。

このコンテキストに描画する場合、Quartzはメモリの指定されたブロック内にビットマップデータとして図形をレンダリングします。

新しいビットマップコンテキストのピクセルフォーマットは、成分毎のビット数、色空間、そして(Image Bitmap Informationの定数として表される)アルファオプションの3つのパラメータによって決定されます。

アルファ値は、描画される時にピクセルの不透明度を決定します。

data:図形がレンダリングされるメモリ内の転送先のポインタを指定します。
このメモリブロックのサイズは、少なくとも(bytesPerRow * height)バイトである必要があります。
iOS 4.0以降とMac OS X v10.6以降では、Quartzでビットマップのメモリを割り当てる場合、NULLを渡すことができます。
これはメモリリークの問題を減少させ、自身でメモリ管理をする必要が無くなります。

width:必要なビットマップのピクセル幅を指定します。

height:必要なビットマップのピクセル高さを指定します。

bitsPerComponent:メモリ内のピクセルの各成分に使用するビット数を指定します。
例えば、32ビットピクセルフォーマットでRGB色空間の場合、1成分あたり8ビットの値を指定することになります。
サポートされているピクセルフォーマットのリストについては、『Quartz 2D Programming Guide』の『Graphics Contexts』を参照してください。

bytesPerRow:ビットマップの行毎に使用するメモリのバイト数を指定します。

colorspace:ビットマップコンテキストで使用する色空間を指定します。
インデックス色空間はビットマップグラフィックスコンテキストでサポートされていないことに注意してください。

bitmapInfo:ビットマップがアルファチャンネルを含む場合、ピクセル内におけるアルファチャンネルの相対的な位置と、ピクセル成分が浮動小数点または整数値かどうかの情報を定数で指定します。
アルファチャンネル情報を指定する定数はCGImageAlphaInfo型で宣言されていますが、このパラメータに安全に渡すことができます。
また、CGBitmapInfo型に関連付けられている他の定数を渡すこともできます。
(CGBitmapInfoとCGImageAlphaInfo定数についての詳細はCGImageリファレンスを参照してください)
ピクセルあたりのビット数、ピクセル成分あたりのビット数、CGBitmapContextCreate関数で使用するビットマップ情報など、色空間を指定する方法についての例は、『Quartz 2D Programming Guide』の『Graphics Contexts』を参照してください。

Image Bitmap Information

ビットマップ画像の成分情報。

enum {
    kCGBitmapAlphaInfoMask = 0x1F,
    kCGBitmapFloatComponents = (1 << 8),

    kCGBitmapByteOrderMask = 0x7000,
    kCGBitmapByteOrderDefault = (0 << 12),
    kCGBitmapByteOrder16Little = (1 << 12),
    kCGBitmapByteOrder32Little = (2 << 12),
    kCGBitmapByteOrder16Big = (3 << 12),
    kCGBitmapByteOrder32Big = (4 << 12)
};
typedef uint32_t CGBitmapInfo;

kCGBitmapAlphaInfoMask
アルファ情報のマスク。
ビットマップに含まれているアルファチャンネルの指定と、どのようにアルファチャンネルを生成するかを指定する際に、アルファ情報の抽出に使用します。

kCGBitmapFloatComponents
ビットマップの成分は浮動小数点値です。

kCGBitmapByteOrderMask
ピクセルフォーマットのバイトオーダーです。

kCGBitmapByteOrderDefault
デフォルトのバイトオーダーです。

kCGBitmapByteOrder16Little
16ビットのリトルエンディアンフォーマットです。

kCGBitmapByteOrder32Little
32ビットのリトルエンディアンフォーマットです。

kCGBitmapByteOrder16Big
16ビットのビッグエンディアンフォーマットです。

kCGBitmapByteOrder32Big
32ビットのビッグエンディアンフォーマットです。

アプリケーションはメモリ内に格納するピクセルデータを、ARGBフォーマットを使用して、どのようにデータの読み込むかを処理する必要があります。

コードが正確に記述されていない場合、データを読み違えて色やアルファが間違った表示になる可能性があります。

Quartzのバイトオーダー定数は、ピクセルフォーマットのバイトオーダーを指定します。

Quartzのバイトオーダーの指定には、適切な定数とbitmapInfoパラメータをビット単位のOR演算子で組み合わせて使用します。

CGColorSpaceRelease

void CGColorSpaceRelease(
    CGColorSpaceRef cs
);

色空間の保持カウントを減らします。

この関数はCFReleaseと同等で、csパラメータがNULLの場合以外ではエラーは発生しません。

cs:解放するQuartzの色空間を指定します。

コンテキスト内での描画矩形のクリア)

コンテキストにおけるテクスチャの描画領域を、CGContextClearRectでクリア(初期化)します。

CGContextClearRect

void CGContextClearRect (
    CGContextRef c,
    CGRect rect
);

透明な矩形で塗りつぶします。

指定されたコンテキストがウィンドウまたはビットマップコンテキストの場合、Quartzは効果的に矩形をクリアします。

他のコンテキスト型の場合、Quartzはデバイスに依存した方法で矩形を塗りつぶします。

ただし、他のウィンドウまたはビットマップコンテキストでこの関数を使用しないでください。

c:矩形を塗りつぶすグラフィックスコンテキストを指定します。

rect:ユーザ空間座標の矩形を指定します。

コンテキスト内でのユーザ座標系の原点の変更)

GLFun(2)~QuartzFunとGLFunの違い』で述べたように、UIKit座標系は左上角を原点に、Core Graphics(Quartz)座標系は左下角を原点としています。
(QuartzFunはグラフィックスコンテキストをUIKitの関数で生成しているため、Core Graphics関数で描画しているもののUIKit座標系になっています)

OpenGL座標系もCore Graphics座標系と同じ左下角が原点なのですが、テクスチャ座標系はその逆に左上角が原点になっています。

テクスチャ用画像が2の累乗サイズなら問題無いのですが、そうでない場合は2の累乗サイズの領域内に画像が描画されるため、隙間が空いてしまいます。

この際、テクスチャ用画像の生成をCore Graphicsのコンテキスト生成関数CGBitmapContextCreateで行っているため、画像はCore Graphics座標系である左下角を原点として描画されます。

7721

テクスチャの表示領域は左上角が原点のテクスチャ座標系で指示するため、このままでは表示領域の指示を原点を起点として扱うのに不便なので、原点を隙間分移動させます。

CGContextTranslateCTMで、コンテキスト内のユーザ座標系の原点を移動させます。

第一引数は当該コンテキストを指定します。

第二引数はx座標の移動分ですが、どちらも原点は左側なので0を指定します。

第三引数はy座標の移動分で、2の累乗に補正された高さheightから元画像サイズの高さimageSize.heightを引いた差分を指定します。

7722

こうすることで画像データの有効な描画領域を左上角の原点にすることができます。

CGContextTranslateCTM

void CGContextTranslateCTM (
    CGContextRef c,
    CGFloat tx,
    CGFloat ty
);

コンテキスト内のユーザ座標系の原点を変更します。

c:グラフィックスコンテキストを指定します。

tx:指定されたコンテキスト内のユーザ空間のユニットで、座標空間のx軸の変位量を指定します。

ty:指定されたコンテキスト内のユーザ空間のユニットで、座標空間のy軸の変位量を指定します。



参考文献

iOS OpenGL ESプログラミングガイド

OpenGL ES 1.1 Reference Pages

CGColorSpace Reference

碧色工房-blue studio-/C言語/ポインタとメモリと型(構造体)の関係 (3)

CGBitmapContext Reference

CGImage Reference

CGContext Reference

はじめての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 他

商品詳細を見る






Wave SoundTouch music system IV
Calendar
12 | 2012/01 | 02
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

Wave SoundTouch music system IV
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