Xcode(6回目) [Xcode]


OpenGLの参考と成るサンプルが見つかりません。と言うより、Dev CenterのサンプルもXcode4のために紆余曲折しているみたいです。大幅なアップデートになるのか知れませんが、これも、Objective-C++の強化のためかも知れません。なので取りあえず、MacGLEssentialsと言うC言語混在のアプリを選んでみました。これはiPoneとも混在です。ビルド実行すると以下のようになります。

     怪物怪物.png

これが3Dでグルグル回転すると言うアプリです。iPoneのゲームでちょっと使えそうですが、これだけではゲームになりません。が、これだけでも私なら考えてしまいます。興味ある人ならダウンロードして調べるでしょうから、今回は長いクラスごとのコードはこれ以上載せません。只、私の興味あるところと、留意点だけです。

Classesの中にある自動で出来るAppDelegateクラスは、これ以上拡張しない限り意味がないので参照から削除しました。それでも、ちゃんとコンパイルできます。これは、インターフェースビルダーを使ってウインドウとGLViewを表示するので、GLUT.frameworkは有りません。C言語で扱っているのは、ユーティリティー群です。その中でmatrixUtil.cの一部を見たいのですが、この表現です。

void mtxRotateZMatrix(float* mtx, float rad)

{

// [ cos -sin 0  0 ]   [ 0 4  8 12 ]

// [ sin cos  0  0 ] x [ 1 5  9 13 ]

// [ 0   0    1  0 ]   [ 2 6 10 14 ]

// [ 0   0    0  1 ]   [ 3 7 11 15 ]

float cosrad = cosf(rad);

float sinrad = sinf(rad);

float mtx00 = mtx[ 0];

float mtx04 = mtx[ 4];

float mtx08 = mtx[ 8];

float mtx12 = mtx[12];

mtx[ 0] = cosrad*mtx00 - sinrad*mtx[ 1];

mtx[ 1] = sinrad*mtx00 + cosrad*mtx[ 1];

mtx[ 4] = cosrad*mtx04 - sinrad*mtx[ 5];

mtx[ 5] = sinrad*mtx04 + cosrad*mtx[ 5];

mtx[ 8] = cosrad*mtx08 - sinrad*mtx[ 9];

mtx[ 9] = sinrad*mtx08 + cosrad*mtx[ 9];

mtx[12] = cosrad*mtx12 - sinrad*mtx[13];

mtx[13] = sinrad*mtx12 + cosrad*mtx[13];

}

迷わないように、行列式をコメントしてから、z軸の角度の変化ごとの式を作っています。このCファイルは最初から延々と続きます。radは、rad=deg * (M_PI/180.0f)と定義しているので、ある角度です。しかしこういった記述は、実に迷います。出来上がったアプリケーションを見ても、どの部分の事なのか、何をしているのか迷います。なので、配列に於ける初歩的なミスを載せておきます。


#include <stdio.h>


int main (int argc, const char * argv[]) {

    int mtx[7], i;

mtx[0] = 0; //答え:mtx[0]

mtx[1] = 1; //答え:mtx[1]

mtx[2] = 4; //答え:mtx[4]

mtx[3] = 5; //答え:mtx[5]

mtx[4] = 8; //答え:mtx[8]

mtx[5] = 9; //答え:mtx[9]

mtx[6] = 12; //答え:mtx[12]

mtx[7] = 13; //答え:mtx[7]

i = 0;

for (i =0; i < 8; i++) {

printf("mtx[%d]\n",mtx[i]);

//return i;

}

    

    return 0;

}

慣れた人なら分かるでしょうけれども、これは意図した結果が表示されない悪い例です。意図した事は、コンソール上で、mtx[0]~mtx[13]迄を表示させたかったのですが、mtx[12]が出た後、出て来たのが、mtx[7]でした。これは、上文の float mtx00 = mtx[0]が配列として宣言していたので、できると思ったからやったのですが、カウンターはintで宣言したmtx[0]を0カウント、つまりカウントしないで1から始まり、7個配列を作ったのでした。とすると8個目のmtx[7] = 13は無視されますが、for文は、0から8回繰り返されますから、値がないので8個目としての7が代入された訳です。

また、//return i;の//をはずすとどうなるでしょうか。分からない人はやってみて下さい。

しかし上のファイルは効率がよく有りません。この方が、プログラム的です。

#include <stdio.h>


int mtx[8] = {0, 1, 4, 5, 8, 9, 12, 13};


int main (int argc, const char * argv[]) {

    int  i = 0;

for (i =0; i < 8; i++) {

printf("mtx[%d]\n",mtx[i]);

}

    return 0;

}

これならすっきりします。また、main関数外で宣言した配列は、メイン関数内で宣言しても結果は同じでした。

このサンプルは私に取ってかなり圧巻なので、OpenGL入門でネットを調べると結構有るんですねえ。なので、基本を押さえるならそちらの方を参照した方がましなので、ここでは、Think Differentに終始する事にしました。

他のOSと大きく違うのが、ヘッダーファイルのフレーム名の違いではないでしょうか。<OpenGL/gl.h>のところが、<GL/gl.h>や<GLUT/glut.h>が<GL/glut.h>とかになり、ウインドウズの場合は、<window.h>もインクールドしなければならないようです。なので、Mac OS Xでは動作しないのも有ります。というより、アップルで作る解説のホームページは殆ど皆無でした。逆に、Xcodeには、AppKit.frameworkの中にNSOpenGL.h, NSOpenGLLayer.h, NSOpenGLView,QuartzCore.frameworkの中には、CAOpenGLLayer.h,CARenderer.hという独自のヘッダーファイルも用意されています。

互換性は非常に高いですが、真に開発するのであれば、それぞれのOSに慣れないと駄目なようです。

ところでC言語の関数である、例えば void init( ){ }とObjective-Cである (void)init{ }とはどんな違いが有るのか、不思議に思った事はないでしょうか。なので、少しいじってみました。通常であればObjective-Cの場合、例えばこういった形に成ります。

+ (id)defaultAnimationForKey:(NSString *)key{}それをこうしました。

+ [id defaultAnimationForKey]:(NSString)key{}明らかにエラーなのですが、さてコンパイラーは何と答えるでしょうか。答えは、Expected selector for Objective-C methodと出て来ました。直訳すれば、オブジェクティブCのためのセレクターを予期していた。idはオブジェクトであり大丈夫かなと思いきや、selectorがいけないのでしょうか。では取り得るセレクターに変えてみましょう。+ [id objectAtIndex]:(NSString)keyやはりだめです。では元に戻します。

+ (id)defaultAnimationForKey:(NSString)keyこれではどうでしょう。

今度はこんなエラーが返って来ました。interface type 'NSString' cannot be passed by value; did you forget * in 'NSString'  キーとは文字だと思っていたら、あくまでvalue for keyなんですねえ。ここで言える事は、(型)を持たない値はObjective-Cの場合関数に成り得ないと言う事でした。

ではC/C++言語の場合はどうなんでしょうか。どういった場合関数だと判断できるのでしょうか。例えば、上文にあるこれで見てみましょう。void mtxRotateZMatrix(float* mtx, float rad)

C言語にどっぷり浸かっている人には、これが関数だと言うでしょう。でもそれだと、smalltalkの流れを汲む関数には抵抗が有るのではないでしょうか。ちょっと前迄は、所詮消え行く言語と思っていたはずですが、思惑はiPoneの登場でがらりと変わってしまいました。だからって、Androidなのでしょうか、Androidはモトローラの開発ソフトであり、モトローラと言えば嘗てマッキンッシュのCPUを一手に引き受けていた会社なんですが、どうなんですかね。経済トップの状況なんか分かりませんが、包囲網に囲まれているような気がするのですが、まあ、私にはどうでも良いか。

しかしCの関数をよくよく考えると、メッセージ式みたいな関係があります、最初の剥き出しのvoidはスペースで区切られた、次の値を受け止められます。つまりレシーバーになっているのです。しかし、この手のやり方は、ここで使っているので、なかなか拡張は出来ません。しかし、その単純さのお陰で開発が進み、全てのOSの基本と成りました。続く


タグ:XCode
nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:学問

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

Xcode(5回目)Xcode(7回目) ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。