PSPSDK試用の日記です


by pspborder
カレンダー
S M T W T F S
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
こんにちわぁ、PSPBORDERです。

サイト更新しなければと思いつつ、早半年が過ぎ
(すっかりこのブログ忘れかけてましたが
...いや、正確にはブログのIDとパスワードが
どうにも思い出せず...^^;)

久しぶりにログオンしてみたら、結構アクセス数があったり(^^:)

待たせたね、みんな(^o^)ノ

これからがんがん、また行くのでヨロシクネ☆

あ、そうそうここのブログ放置してた間なにやってたかと
いうと、ロリポップで別のバカねたやってたり。

 『うそぴょんブログ!』です。

  URL: http://blog.usopyon.net/


そっちの方もヨロシクおねがいしますよ!

ここをクリックで人気blogランキングへ(ご協力お願いします)

[PR]
# by pspborder | 2006-04-01 20:57 | お知らせ
画面が地味で、地味でと評判のこのサイト!

このままではやる気にも関わりますのでサイトの
修正を行おうかと思います(悲しい事に内容を
充実という方向には行かないのです!びしっ)。

とりあえず土日、ちょこちょこいぢるので
その間おかしな動きしたり、妙な記事(てすととか)
あがるかもです。気にしないようにしてくださいねっ(>_<)ノ



ここをクリックで人気blogランキングへ(ご協力お願いします)
[PR]
# by pspborder | 2005-08-05 10:43 | お知らせ
PSPSDKの定数追加や若干の仕様変更により、心理的にかなりのダメージ
を受けた上、PSPのファームウエア・アップグレードでWEBブラウザが
使えるようになったりとか罠満載で続行も危ぶまれる『PSPSDKプログラミング
日誌』ですが、それでも、踏ん張って付いて来てくれるものと信じてがんばり
ます。...ええ、がんばりますとも...無駄に(;_;)

『3Dグラフィックス入門(その2) GU描画 』、『3Dグラフィックス入門(その2)
GU描画 』を経て、PSPのGUとGEを使用する際の初期化と描画命令に
ついて簡単に説明してきました。そう、もうあなたはPSPで自由自在に3D
グラフィックスをもてあそぶ事ができるでしょう...できる...といいな(・_・;)

今回はGUやGEについての説明というより、3Dグラフィックスの説明に
なります(でも難しい事は説明できないので、都合が悪い場合はスルー
です。お約束です)。

今回も長くなってしまいました。頂点座標についての説明に留まります。

【頂点定義について】
 GUにポリゴン描画(三角形だけどちゃんと覚えてるかな?)を行う場合
 まず頂点座標を定義します...がめんどいので次回に回します!といって
 いた部分ですがC言語の構造体で下記の様に定義されています。前回
 SDKライブラリ側で定義されていると言いましたが、大嘘です...cubeデモ
 側で定義されてました(^^;)...誰か突っ込んで欲しいと思う今日この頃
 です(恥ずかしいので、原文こっそり修正しました...鋭意日記捏造中)。

 struct Vertex
 {
  float u, v; // 投影面の座標系を横方向=U, 縦方向=Vと表記する
  unsigned int color; // 頂点カラー
  float x,y,z; // 頂点座標
 };

 ふふっ、この簡単な定義に3Dの基礎がみっちり詰め込まれているではない
 ですか、せっかくなので、説明用に使わせて貰います。
 3Dポリゴン(三角形)を描画するために頂点を三つ用意してあげます。その
 個々の頂点は上記Vertex構造体の属性を持ちます。で当然3D空間という
 物があって、そこでの座標となります。構造体のメンバでいうとx,y,zがそれに
 あたります。各値はfloat(小数点型:ここでfloatの精度に関しては気にしない
 でください、PSPの場合同じMIPS32でも違うという事になってます...普通に
 使う分には変わらないはずですから、ああfloat型なんだねと漠然と理解して
 くれると非常に助かります)で表記されます。でX,Y,Zそれぞれなんですが
 Xは画面に対して横方向(幼稚な表現でごめん^^;)Yは縦方向、Zは奥行き
 となります。座標をX,Y,Zを表す際に右手座標系と左手座標系というのが
 ありますが、右手座標系です(のはずです...間違ってたらごめん^^;)

 右手座標系について(ううっ、図使いたい^^;)
  親指(X)、 人差し指(Y)、 中指(Z)
  それぞれの値はXは右に向かって増える、Yは上に向かって増える、
  Zは奥から手前に向かって増えるです。

  ちなみに、左手座標だとZだけ逆になります(手前から奥に向かって値が
  増える)

 Vertex構造体u, vメンバについてですが、これは透視変換への投影面
 等に使用されます。何を言っているかというと、せっかく3Dの座標をセット
 して3D空間をイのままに使えるようになっても、所詮PSPの液晶画面は
 2Dです(スターウォーズのホログラフィみいに物が浮かぶわけじゃない
 です)。だから、最終的に2Dに投影してあげる必要があります。その際
 にPSP画面上のどこにあたるかを表します。当然視点を変えると座標は
 変わらなくてもU,Vの値は変わります。あと投影は画面だけではなく
 描画するオブジェクトに対してのU,Vに使用したりもします(テクスチャ
 マッピング)...残念ながら、今回のサンプルではU,Vを求めるのは
 GU+GEのお仕事なので気にする必要ありません。
 6面体(cube)なので面は6面で1つの面を2つの3Dポリゴンで描画
 していますので頂点数は6X2=12個です。

 Vertex構造体colorメンバですが、これは頂点色です。今回の例では
 3Dポリゴンごとに同じ頂点色をセットしていますが、これを頂点毎に
 変える事が出来ます(シェーディングモードがグーローシェーディング
 なので)


==============================================
 頂点定義例(PSPSDK cubeデモより抜粋)
==============================================
 struct Vertex
 {
  float u, v; // 投影面の座標系を横方向=U, 縦方向=Vと表記する
  unsigned int color; // 頂点カラー
  float x,y,z; // 頂点座標
 };

struct Vertex __attribute__((aligned(16))) vertices[12*3] =
{
{0, 0, 0xff7f0000,-1,-1, 1}, // 0
{1, 0, 0xff7f0000,-1, 1, 1}, // 4
{1, 1, 0xff7f0000, 1, 1, 1}, // 5

{0, 0, 0xff7f0000,-1,-1, 1}, // 0
{1, 1, 0xff7f0000, 1, 1, 1}, // 5
{0, 1, 0xff7f0000, 1,-1, 1}, // 1

{0, 0, 0xff7f0000,-1,-1,-1}, // 3
{1, 0, 0xff7f0000, 1,-1,-1}, // 2
{1, 1, 0xff7f0000, 1, 1,-1}, // 6

{0, 0, 0xff7f0000,-1,-1,-1}, // 3
{1, 1, 0xff7f0000, 1, 1,-1}, // 6
{0, 1, 0xff7f0000,-1, 1,-1}, // 7

{0, 0, 0xff007f00, 1,-1,-1}, // 0
{1, 0, 0xff007f00, 1,-1, 1}, // 3
{1, 1, 0xff007f00, 1, 1, 1}, // 7

{0, 0, 0xff007f00, 1,-1,-1}, // 0
{1, 1, 0xff007f00, 1, 1, 1}, // 7
{0, 1, 0xff007f00, 1, 1,-1}, // 4

{0, 0, 0xff007f00,-1,-1,-1}, // 0
{1, 0, 0xff007f00,-1, 1,-1}, // 3
{1, 1, 0xff007f00,-1, 1, 1}, // 7

{0, 0, 0xff007f00,-1,-1,-1}, // 0
{1, 1, 0xff007f00,-1, 1, 1}, // 7
{0, 1, 0xff007f00,-1,-1, 1}, // 4

{0, 0, 0xff00007f,-1, 1,-1}, // 0
{1, 0, 0xff00007f, 1, 1,-1}, // 1
{1, 1, 0xff00007f, 1, 1, 1}, // 2

{0, 0, 0xff00007f,-1, 1,-1}, // 0
{1, 1, 0xff00007f, 1, 1, 1}, // 2
{0, 1, 0xff00007f,-1, 1, 1}, // 3

{0, 0, 0xff00007f,-1,-1,-1}, // 4
{1, 0, 0xff00007f,-1,-1, 1}, // 7
{1, 1, 0xff00007f, 1,-1, 1}, // 6

{0, 0, 0xff00007f,-1,-1,-1}, // 4
{1, 1, 0xff00007f, 1,-1, 1}, // 6
{0, 1, 0xff00007f, 1,-1,-1}, // 5
};
==============================================

こんな感じで六面体(cube)を定義します。
次回は何とか透視変換まで行きたいです(いまだにちゃんと説明できてない)


ここをクリックで人気blogランキングへ(ご協力お願いします)



  
[PR]
# by pspborder | 2005-07-23 22:54 | PSP開発
ぐはぁっ、ファームウエアのアップグレードで
PSPでWEBのブラウズできるようになるそうでちゅ(;_;)

ファームウエアのアップデータダウンロードは7月27日からなの(;_;)
ぐすん...。ついでに白いPSPもでるそうです(白い奴は2005年9月15日
(木)発売にゃ)。

詳細は下記URLより
 http://www.watch.impress.co.jp/av/docs/20050721/scei1.htm


でね、皆さんにひとつ警告。
ファームウエアアップグレードするとね、PSPSDKで作ったプログラム
動かなくなっちゃいます...ぐすん。ううっ、痛いとこついてくるなぁSCE様。

しょうがない、もう一台買うかっ、白いの!
...をいをい何台買えばいいんだよ^^;...もうすでに2台手元にあります。
あ、新しいやつも動かないからねPSPSDKでつったプログラム(・_・)b
しかし、このBLOGもピンチなのじゃよ...いやいや負けないよー(>_<)


ここをクリックで人気blogランキングへ(ご協力お願いします)


あ、そうそう皆様の温かいご支援のせいで、BLOGランキング
滅茶苦茶あがってます、本当にありがとうございます(これからも
よろしくねぇ^^)

===========================
 7月22日 00:52 現在
===========================
ウェブログ (10%) - 461位
プログラム (20%) - 61位 (<- ここ前136位でした^^;)
プレイステーション (60%) - 30位 
家庭用ゲーム機 (10%) - 110位  (<-ここにいたって
                      は800位台、快進撃)
===========================
[PR]
# by pspborder | 2005-07-22 00:50 | お知らせ
恥ずかしながら『人気BLOGランキング』様に参加する事にしました。

貴重な一票めぐんでやろうという、やさしい方おられましたら是非下記の
”ここをクリック...”の部分をクリックしてください。あなたの貴重な1票が
投票されます(無料です)。何卒ご協力お願いします m(_ _)m

ここをクリックで人気blogランキングへ(ご協力お願いします)


...今、プログラム・カテゴリで136位でした(^^)

特に締め切り無く、毎日、投票は受け付けられてます。
気の向いたときで結構ですから(^^)b

人気BLOGランキング様URL: http://blog.with2.net/
[PR]
# by pspborder | 2005-07-20 22:57 | お知らせ
『3Dグラフィックス入門(その3) ジオメトリ演算』
に行く前に...ちょっと小ネタを(^^;)

...やんなきゃ良いのにと思いつつ、PSPSDK最新版の
チエックアウトやっちゃいました。あーあ(-_-;)

...おもいっきり、変わってるよ、GU関連...orz

あ、一通り古いバージョンで説明したら、更新の詳細
説明します(^^;)だから、今はこのままなの、これで
いくの(;_;)

ざっとみて気づいた事書きます(^^)

【おいおい対応すればいい事】
  ・今まで関数呼ぶときに使用していたパラメータで直値で
   していたものは新たに定数が定義され、それを指定します。

   例えば0だった物はGU_XXX_XXXXみたいので指定。

  ・初期化系の関数で、今まで暗黙の了解で0を指定すれば
   良かった物が新たにモード追加されています(ハッキ...調査
   が思った以上に進んでます)。とりあえず0のままでも
   良いみたいですが^^;

  ・GE_SETREG_VTYPE()というわけのわかんないマクロ
   使わなくても良くなりました...今度は定数の指定にて行います。
   わりと判りやすくなった気がします(このマクロ嫌だったんだよなぁ)。

【ちびし~と思っている事】
  ・既存で定義されていた定数が変更になった物があります。
   (書き直す必要がありますTT)値は変わってないので
   見なかったことにするという手もありますが...。

  ・SDKライブリ関数の変更では無いのですが
   matrix_projection()透視変換マトリクス操作関数へ渡す値
   が一部変わってます(^^;)...何故だぁ(>_<)ノ
   ....どうしてくれよう(・_・;)

ま、成長中ですからねぇ、想定外の事をばんばんやってくれますPSPSDK!
はっきり、いって凄く良くするための変更なのでウエルカムなんですが(^o^)

...日誌書き始めるの1ヶ月遅らせればよかった....ぼそっ!

 
ここをクリックで人気blogランキングへ(ご協力お願いします)

  
[PR]
# by pspborder | 2005-07-20 18:08 | PSP開発
ああ、途中間があいてしまいましたね(^^;)
飽きたわけでわないんです。...違うんですG○O2が悪いんです。
...ええ、もう極悪ですとも。

前回は、物凄い勢いでGU初期化について説明しましたが、如何だったで
しょうか?正直むずいので、全部理解する必要ないです。こんなもんかな
程度に押さえといて下さいね。

さて、前回 『3Dグラフィックス入門(その1) GU初期化』でGUに対して
描画の準備が整いました。今回は、GUのプリミティブ(GUで用意して
くれている基本図形など)の描画について説明します。
尚、今回も盛りだくさんなのでデータ表記や、ジオメトリ変換用の関数
の説明は次回に回します(さぁ、のっけから雲行きが怪しく...^^)。

PSPSDKのcubeデモよりGU描画部分のみ抜粋しました。

==============================================
 GU描画の例(PSPSDK cubeデモより抜粋)
==============================================

  ・・・ 中略(関数内のグローバル変数宣言部)

1: struct Vertex __attribute__((aligned(16)))
  vertices[12*3] =
  ・・・ 中略(Vertex=頂点座標)のセット(ここにcubeの形状がっ)
2: };

  ・・・ 中略(メイン関数内描画ロジック)

3: ScePspFMatrix4 projection;
4. ScePspFMatrix4 view;
5: ScePspFMatrix4 world;

6: int val = 0;

   // 描画用ループ
7: for(;;)
8: {
9: sceGuStart(0,list);

    // 画面クリア
10: sceGuClearColor(0xff554433);
11: sceGuClearDepth(0);
12: sceGuClear(GE_CLEAR_COLOR|GE_CLEAR_DEPTH);

    // cubeのマトリクスをセットする
13: matrix_identity((float*)&projection);
14: matrix_projection((float*)&projection,
     5.0f,16.0/9.0f,0.01f,1000.0f);
15: sceGuSetMatrix(GU_MATRIX_PROJECTION,
      &projection);
     
16: matrix_identity((float*)&view);
17: sceGuSetMatrix(GU_MATRIX_VIEW,&view);

18: matrix_identity((float*)&world);
19: matrix_translate((float*)&world,0,0,-3.0f);
20: matrix_rotate((float*)&world,
      val * 0.79f * (M_PI/180.0f),
      val * 0.98f * (M_PI/180.0f),
      val * 1.32f * (M_PI/180.0f));
21: sceGuSetMatrix(2,&world);

     ・・・ 中略(テクスチャーやマテリアルのセット)

    // cubeの描画
22: sceGuDrawArray(GU_PRIM_TRIANGLES,
      GE_SETREG_VTYPE(GE_TT_32BITF,GE_CT_8888,
      0,GE_MT_32BITF,0,0,0,0,0),12*3,0,vertices);

23: sceGuFinish();
24: sceGuSync(0,0);

25: sceDisplayWaitVblankStart();
26: sceGuSwapBuffers();

27: val++;
28: }
==============================================


【描画の大まかな流れについて】
 例によってだらだら書いてますのでわかりにくいです(^^;)
 なのでポイントをまず先に記載しますね。これに沿って説明
 していきましょう。

  ・cube頂点座標を用意します。
  ・マトリクス演算用変数の宣言。
  ・描画用のループを用意します(無限ループ)
  ・描画用のコマンドリスト開始宣言をします(終了までが
   描画対象です)
  ・ 画面をクリアします(描画前に必ずクリアします)
  ・透視変換用マトリクスをセットします。
  ・ビュー用マトリクスをセットします。
  ・ワールド座標用マトリクスをセットします。
   (描画ループ内でcubeの形状、透視変換、ビューともに
    毎回固定ですがワールド座標用のマトリクスに回転を
    加える事でcubeを回転させています)
  ・GUプリミィティブ描画にてcubeの描画を行います。
  ・描画用のコマンドリスト終了宣言をし、GUに実行要求を行います。
  ・次の描画の準備をします。 
  ・描画用のループに戻ります。



【cube頂点座標について】
 ううっ、cube形状を定義するための重要な情報ですが詳細
 次にまわします(その方が説明に都合が良いので)。ここは
 Vertexという頂点定義の型があってそれをDMA転送のきり
 の良い形で頂点の情報を定義するんだなぁと思ってください。
 1行目から3行目がそうです。ここでセットされている頂点座標
 がcubeの形(大きさや位置も含めた)になります。

  1: struct Vertex __attribute__((aligned(16)))
    vertices[12*3] =
  ・・・ 中略(Vertex=頂点座標)のセット(ここにcubeの形状がっ)
  2: };


【マトリクス演算用変数について】
  詳細は次回参照ですが、マトリクスとは行列の事を指します。
  色んな行列を用意していますが、今回は透視変換用マトリクス、
  ビュー用マトリクス、ワールド座標用マトリクスがあります。
  凄い乱暴な言い方をしますが(次回説明するから^^;)
  透視変換用マトリクスは3DからPSPの2D画面への置き換え
  (レンダリングとかラスタライズとかいいます)で使います。ビュー
  用マトリクスは3D空間の見える部分の切り出し、ワールド用
  マトリクスはオブジェクトを配置している空間の操作を行うために
  使用します(cubeしか配置してないのでワールドを回転させると
  cubeが回転してみえるでしょ)。変数はScePspFMatrix4(4
  列の行列からなるマトリクス)型で宣言します(3行から5行目まで)。

  3: ScePspFMatrix4 projection;
  4. ScePspFMatrix4 view;
  5: ScePspFMatrix4 world;


【描画用のループを用意します(無限ループ)について】
 GUに何か描画させるためにはひっきりなしに描画コマンドを送り
 つづける必要があります(Windows見たいに他のアプリが画面を
 更新する事はないので、別に画面変わんないなら止めてていいじゃん
 と思うでしょうが、パッドとかのボタン押したかどうか判定も必要なので...)。
 で、必ず描画を行うループが必要になります。ループ自体は無限ループ
 で、これを抜けルためにはPSP本体のHOMEキーを押します(そのために
 プログラム開始時点で割り込み用スレットの定義を行っていますが、3D
 プログラミングとは何にも関係無いし定型的な処理なので割愛させて
 いただきます)。HOMEキーを押すとループを抜けcubeプログラムは
 終了し、PSPのブラウザへ戻ります。描画ループは7行目から28行目
 までです。

 意外に重要なのが6行目で宣言されているvalという整数の変数ですが
 これはループを繰り返すごとに1づつカウントされていきます(27行参照)。
 じゃ、valは何に使ってるのか?というとcubeの回転に使われてます。
 27行をコメントアウトして無効化すると判りますが、cubeが回転しない
 とてもつまらないプログラムになります。あと、valは無限にカウントしつづ
 けますのでいつか(符号付32bit整数なので2の(32-1)乗-1まで
 カウントしたところで何チャラオーバーフローでプログラム自体がストップ
すると思います。時間的にはさらに60で割ると秒数がでます。かなり
長い事頑張ります)。あくまでもサンプルなのでこういう作り方をしていますが
こういうのは見習わないようにね(^^;)

  6: int val = 0;
  7: for(;;)
  8: {
  ・・・   中略(描画の要求が入ります)
  27: val++;
  28: }


【GUコマンドリスト開始と終了について】
 前回の『3Dグラフィックス入門(その1) GU初期化』で説明したのと
 全く一緒なのでそちらを見てください。cubeの描画はsceGuSync()
 実行時に行われます。

  9: sceGuStart(0,list);

     ・・・ GUに送る要求(今回は計算済のマトリクスと
        プリミティブ描画)

  23: sceGuFinish();
  24: sceGuSync(0,0);


【 画面クリアについて】
  毎回描画を始める前に画面全体をクリアします(正確には描画バッファ
  の内容を指定カラーで埋めるだけです)。10行目のsceGuClearColor()
  で画面消去のための色を指定します。今回、描画バッファは
  GE_PSM_8888(24Bitフルカラー)で指定しているので色は24bitです。
  頭ffは固定です。
  微妙に違うんですが、背景色としてsceGuClearColor()を考えてもいいかも
  です。

  あと被写界深度バッファ(これも前回説明しましたね)もクリアするので、
  それも指定します。11行目のsceGuClearDepth()がそれにあたり
  ます。
 
  実際に描画バッファや被写界深度バッファを指定値でクリアするのは
  12行目のsceGuClear()のお仕事です。ここら辺は10行目の指定色
  値以外は固定でいいです。

      // 画面クリア
  10: sceGuClearColor(0xff554433);
  11: sceGuClearDepth(0);
  12: sceGuClear(GE_CLEAR_COLOR|GE_CLEAR_DEPTH);


【各マトリクスのセットについて】
  詳細は次回に回しますがジオメトリのマトリクス演算に関しては
  GEでは無くC言語のプログラムで行う事になります(理由は前回
  説明しました)。matrix_XXXX()という関数がそれを行ってくれます。
  大体パターンは下記の流れです。
    ・matrix_identity()でマトリクス変数の初期化
    ・マトリクスの変換
       matrix_projection()で透視変換作成とか
       matrix_translate()で移動とか
       matrix_rotate()で回転とか

    ・マトリクス値のGUへのセット
       sceGuSetMatrix()で行います(正確にはGE経由だと
       思われ...)
       変換が必要の無い物はこれで直に渡すですよ。

    例によって使えないコメント付記しておきますね(^^)

    // 透視変換用マトリクスをセットします。
    13: matrix_identity((float*)&projection);
    14: matrix_projection((float*)&projection,
           5.0f,16.0/9.0f,0.01f,1000.0f);
    15: sceGuSetMatrix(GU_MATRIX_PROJECTION,
            &projection);

    // ビュー用マトリクスをセットします。  
    16: matrix_identity((float*)&view);
    17: sceGuSetMatrix(GU_MATRIX_VIEW,&view);

    // ワールド座標用マトリクスをセットします。
    // ほら、変数valを使用して回転させてるでしょ!
    18: matrix_identity((float*)&world);
    19: matrix_translate((float*)&world,0,0,-3.0f);
    20: matrix_rotate((float*)&world,
            val * 0.79f * (M_PI/180.0f),
            val * 0.98f * (M_PI/180.0f),
            val * 1.32f * (M_PI/180.0f));
    21: sceGuSetMatrix(2,&world);


【GUプリミィティブ描画について】
  既に頂点座標として定義してある変数を(cubeの頂点座標群である
vertices)使用してプリミティブの描画要求を行います。22行目の
  sceGuDrawArray()がそれで、さらにGU_PRIM_TRIANGLES
  を指定してますがこれは三角形(これこそが俗にいうポリゴンで
  あります)です...やりました、ポリゴン描画まで行き着きました。
  ううっ、思えば永い旅路でした(T_T)。
 
  // cubeの描画
  22: sceGuDrawArray(GU_PRIM_TRIANGLES,
        GE_SETREG_VTYPE(GE_TT_32BITF,GE_CT_8888,
        0,GE_MT_32BITF,0,0,0,0,0),12*3,0,vertices);

  当然、色んなプリミティブをsceGuDrawArray()で描画できますが
  違うプリミティブ(例えば線)とか描画するんなら、別の頂点座標変数
  の用意が必要です(表記も微妙に違います)
  
  sceGuDrawArray()のリファレンスはこんな感じで

     PARAM1: prim - 描画するプリミティブのタイプ
       現在PSPSDKで使用できるGUプリミティブ
       (OpenGLとかのプリミティブもこんな感じです)
        GE_PRIM_POINTS
        GE_PRIM_LINES
        GE_PRIM_LINESTRIPS
        GE_PRIM_TRIANGLES
        GE_PRIM_TRISTRIPS
        GE_PRIM_TRIFANS
        GE_PRIM_SPRITES

     PARAM2: vtype - 頂点タイプ
       GE_SETREG_VTYPE()マクロを指定して指定
       します(pspgu.h参照)特に描画バッファのモード
       変えないならこのままでも(^^;)

     PARAM3: count -  頂点情報の数(頂点の数じゃないよ)
                     頂点情報vertices[12*3] と宣言
                     されてますので、ここで指定する数は
                     12*3です。

     PARAM4: indices -  頂点情報を他のプリミティブと兼用する
                    わけではないので先頭の0でいいです。
                    兼用するなら配列内でのインデックスを
                    指定してください。

     PARAM5: vertices -  頂点情報が格納されている変数のポインタ
                     今回はverticesを使用しますので、
                     verticesを指定します。



【次の描画について】
  描画が行われましたので次の描画の準備をします。
  ・次のVBlank割り込を待ちます(25行)

  ・作業用バッファと描画用バッファを切り替えます(26行)。毎回描画用
  バッファと作業用バッファを切り替えて使います。

  25: sceDisplayWaitVblankStart();
  26: sceGuSwapBuffers();


ぬおおおっ、今回も物凄い勢いで詰め込みましたがいかかだったでしょうか?
たかだか27行のプログラムにこんな説明が入るなんて...何て効率の悪い
...私ってば頭が悪いんでしょうか?(T_T)...既に日記じゃないし!

あ、次回で何とかジオメトリ変換とかマトリクスの救済をしたいです(^^;)


ここをクリックで人気blogランキングへ(ご協力お願いします)
[PR]
# by pspborder | 2005-07-19 11:18 | PSP開発
とりあえず、ヘルプを入手できたので
先に『3Dグラフィックスが動いた日』で取り上げた”cube”デモで
解説していきます(途中で飽きたら止めます)。

今回は、GU(グラフックス・ユニットの略でPSPのググラフィッフックスチップ
を指します)の基本的な使用方法と、初期化まで説明します。編集の都合上
おかしなところで改行してたりしますが、気にしないで下さい(サンプルには
動く物がちゃんと入ってますから)

PSPSDKのcubeデモよりGU初期化部分のみ抜粋しました。

==============================================
 GU初期化の例(PSPSDK cubeデモより抜粋)
==============================================
1: static unsigned int __attribute__((aligned(16)))
       list[262144];

・・・ 省略

2: sceGuInit();
3: sceGuStart(0,list);
4: sceGuDrawBuffer(GE_PSM_8888,(void*)0,BUF_WIDTH);
5: sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,
       (void*)0x88000,BUF_WIDTH);
6: sceGuDepthBuffer((void*)0x110000,BUF_WIDTH);
7: sceGuOffset(2048 - (SCR_WIDTH/2),2048 -
       (SCR_HEIGHT/2));
8: sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
9: sceGuDepthRange(0xc350,0x2710);
10: sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
11: sceGuEnable(GU_STATE_SCISSOR);
12: sceGuDepthFunc(GE_TEST_GEQUAL);
13: sceGuEnable(GU_STATE_ZTE);
14: sceGuFrontFace(GE_FACE_CW); // NOTE: not CCW
15: sceGuShadeModel(GE_SHADE_GOURAUD);
16: sceGuEnable(GU_STATE_CULL);
17: sceGuEnable(GU_STATE_TEXTURE);
18: sceGuFinish();
19: sceGuSync(0,0);

20: sceDisplayWaitVblankStart();
21: sceGuDisplay(GU_DISPLAY_ON);

・・・ 省略
==============================================


【GUシステムの初期化について】
  GUを使用するにあたって必ず1回だけ、初期化を行います。
  必ず、何らかの要求をGUに対して行う前に初期化を行って下さい。
  3行目がそれにあたります。パラメータはありません。

  3: sceGuInit();


【GUコマンドリストについて】
  GUに送信するGUアセンブリ(コマンドみたいの)はコマンドリスト
  として事前に用意したコマンドリスト配列変数にGU用のライブラリ
  関数経由でセットします。描画の直前にコマンドリスト変数はDMA
  転送でGUに送られます。そこで注意なのが、DMA転送に都合の
  よい境界サイズでこのコマンドリスト配列を用意するのがポイントです。

  1: static unsigned int __attribute__((aligned(16)))
       list[262144];

  1行目のこの部分がそうです。以降、配列変数listはずーっと使われる
  重要な変数です。覚えておきましょう。__attribute__((aligned(16)))
  というのがDMA転送に都合のよい境界サイズです(とりあえずコマンドリスト
  変数はこのままで良いです...少し配列のサイズがサンプル用としては
  大きすぎる気がしますが...)。あと、何かGU(GEもですが...)に間する
  ライブラリ関数sceXXXX()と関数を実行するたびに実際にGUに送られる
  GUアセンブリがこの配列変数listに蓄えられていきます。


【GUコマンドリスト開始と終了について】
  じゃぁ、無限に配列変数listを蓄えるだけなのかというと、そういうことでは
  なくていつかは完了になります。GUコマンドリストの開始と終了は下記の
  用に行います。今回は初期化の部分を抽出してみましたが、ポリゴンの
  描画を行う際にも、GUコマンドリスト開始と終了を繰り返します。

  3: sceGuStart(0,list);

     ・・・ GUに送る要求

  18: sceGuFinish();
  19: sceGuSync(0,0);

  3行目のsceGuStart()はこれからコマンドリスト(配列変数list)を使います
  よという宣言です。当然、第2引数には配列変数listの先頭アドレスが指定
  されていますので、この時点以降のGUに対する要求はこの変数の先頭
  から順に積み上げられていきます。第1引数の0は気にしないで下さい。
  今のPSPSDKでは0で必ずセットする事になっています(調査が進んで
  いないのと、実装が特に無いため) 注:将来的には変わる可能性あります。

  18行目のsceGuFinish()でコマンドの完了を宣言します。

  19行目のsceGuSync()にて一括でコマンドを実行します。これも第1、第2
  引数共に0でセットしてください。 注:将来的には変わる可能性あります。

   
  毎回、何かGUに要求するたんびに、これの繰り返しです。



【GUに送る初期化情報について】
  ...多いです。ちゃんと説明するべきなんでしょうが大変なのでコメント
  のみ付加しときます。多分画面モード変えないなら殆ど使いまわし
  ができるはずなので。あと、各種バッファに割り当てられているアドレス
  ですが詳細の記載がヘルプにないのでしばらく暗黙の了解としてそのまま
  同じ値を使用します。

  4: sceGuDrawBuffer(GE_PSM_8888,(void*)0,BUF_WIDTH);
    GUが使用する描画バッファについて設定を行います。
    
    パラメータ
     PARAM1: psm - レンダリングや 表示を行う際のピクセル深度
     PARAM2: fbp - VRAMのどこから描画バッファに使うかを指定
                します。(オフセット値)
               特に理由が無い限り。0=VRAM原点から描画バッファ
               として使用します。
     PARAM3: fbw - フレームバッファの幅 (ブロックの並び)
               フレームバッファの幅をブロックの並びで
               指定します。BUF_WIDTHは定数として
               プログラム側で定義している物で値は512です。

   5: sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,
             (void*)0x88000,BUF_WIDTH);
    GUが使用する描画バッファについて設定を行います。
     PARAM1: width - 描画バッファ幅(ピクセルサイズ)
               SCR_WIDTHは定数として
               プログラム側で定義している物で値は480です。
     PARAM2: height - 描画バッファ高さ(ピクセルサイズ)
               SCR_HEIGHTは定数として
               プログラム側で定義している物で値は272です。
     PARAM3: dispbp - 描画バッファが割り当てられるVRAMアドレス
               0x88000番地のアドレスを固定で割り振っています。
     PARAM4: dispbw - 描画バッファの幅 (ブロックの並び)
               描画バッファの幅をブロックの並びで
               指定します。BUF_WIDTHは定数として
               プログラム側で定義している物で値は512です。

   6: sceGuDepthBuffer((void*)0x110000,BUF_WIDTH);
    GUが使用する被写界深度バッファについて設定を行います。
    被写界深度バッファ(デプスバッファ)は視点から見た物体の
    前後関係を把握するための領域です。この被写界深度範囲外の
    物体は描画されない。
    ので奥行きのカリングとして考えても良いです。
     PARAM1: zbp - 被写界深度バッファが割り当てられるVRAMアドレス
               0x110000番地のアドレスを固定で割り振っています。
     PARAM2: zbw - 被写界深度バッファの幅 (ブロックの並び)
               被写界深度バッファの幅をブロックの並びで
               指定します。BUF_WIDTHは定数として
               プログラム側で定義している物で値は512です。

   7: sceGuOffset(2048 - (SCR_WIDTH/2),2048 -
               (SCR_HEIGHT/2));
    仮想空間のオフセット座標について設定を行います。
     PARAM1: x - X座標のオフセット (範囲0-4095)
     PARAM2: y - Y座標のオフセット (範囲0-4095)


   8: sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
    ビューポートについて設定を行います。
     PARAM1: cx - ビューポート水平方向のセンターX値
     PARAM2: cy - ビューポート水平方向のセンターY値
     PARAM3: width - ビューポートの幅
     PARAM4: height - ビューポートの高さ

   9: sceGuDepthRange(0xc350,0x2710);
    被写界深度バッファの範囲設定を行います。
     PARAM1: near - 被写界深度範囲手前(10進数で50000を指定)
     PARAM2: far - 被写界深度範囲奥(10進数で10000を指定)

  10: sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
    ビューポートの表示面を設定します。
     PARAM1: x - 表示領域X(0)
     PARAM2: y - 表示領域Y(0)
     PARAM3: w - 表示領域幅(480)
     PARAM4: h - 表示領域高さ(272)

  11: sceGuEnable(GU_STATE_SCISSOR);
    GUの状態設定を行います。
     PARAM1: GE_STATE_SCISSOR - ビューポート指定領域の表示

  12: sceGuDepthFunc(GE_TEST_GEQUAL);
    被写界深度テスト機能使用時のテスト内容選択を指定します。
      GE_TEST_GEQUAL: ピクセル値が規定以上ならテストを通過
              基本的に何をやってくれるか判らないので
              しばらく固定で使います。

  13: sceGuEnable(GU_STATE_ZTE);
    GUの状態設定を行います。
     PARAM1: GU_STATE_ZTE - 被写界深度テスト機能を使用します。

  14: sceGuFrontFace(GE_FACE_CW); // NOTE: not CCW
    描画面の設定を行います。
     注意:sceGuEnable(GU_STATE_CULL);が設定されていなければ
        本設定は無効です。
        指定できるのは2種類です。
        GE_FACE_CW - 裏面を描画しない(表面は頂点座標の
              指定が時計回りであるもの)
              通常は、こちらの方で良いです。

        GE_FACE_CCW - 裏面を描画する。


  15: sceGuShadeModel(GE_SHADE_GOURAUD);
    プリミティブオブジェクトのシェーディングモードを指定します。
        指定できるのは2種類です。
        GE_SHADE_FLAT - フラットシェーディング
        GE_SHADE_GOURAUD - グーローシェーディング

  16: sceGuEnable(GU_STATE_CULL);
    GUの状態設定を行います。
     PARAM1: GU_STATE_CULL - プリミティブオブジェクト描画時の
                 カリングを行う(これひょっとすると
                 デフォルトのカリング方法でカリング
                 を行う事かもしれませんがよく判
                 らないです。気にしないことにした)。

  17: sceGuEnable(GU_STATE_TEXTURE);
    GUの状態設定を行います。
     PARAM1: GU_STATE_TEXTURE - テクスチャマッピングを使用
     します。


【描画開始について】
  GU初期化が済みましたので、実際に描画を開始するための準備です。
  20行目と21行目がそれにあたります。

  20: sceDisplayWaitVblankStart();
  21: sceGuDisplay(GU_DISPLAY_ON);

  20行目のsceDisplayWaitVblankStart()はVBlank割り込待ちを
  行います。
  VBlank割り込とは画面書き換えのハードウエア的なイベントのよう
  な物で、実際には画面描画を描画する際に垂直走査線の数分描画を
  終えた後、垂直復帰が行われる(原点に返る事)直前にこの割り込
  みが発生します。
  垂直走査線には奇数ラインと偶数ラインがあります。1秒間に
  奇数偶数合わせて60回発生します(実際には1/60秒以上待たされ
  ている気がするのは気のせいでしょうか?
  あまり、リアルタイムのタイマー的には使用できないと思います)。
 
  難しかったら、次の描画更新を待つ関数と覚えておいてください。

  sceDisplayWaitVblankStart()が戻り、VBlank割り込待ちになったら
  21行目のsceGuDisplay(GU_DISPLAY_ON)でGUへの描画要求は
  画面に表示されるようになります。

  sceGuDisplay()でセットできる値は
    GE_DISPLAY_ON (1) - 表示ON
    GE_DISPLAY_OFF (0) - 表示OFF
  の2種類です。


  これで、いよいよGUに対して描画要求ができるようになりました。
  基本的にGUの初期化は毎回同じです(画面モードとか変えない場合
  ですが...)  


  では続きは次回『3Dグラフィックス入門(その2)』で(^o^)

ここをクリックで人気blogランキングへ(ご協力お願いします)
[PR]
# by pspborder | 2005-07-11 18:51 | PSP開発
とりあえず、いい加減な解説始める前に
オンラインヘルプ(HTMLベース)を読もうと思ったら
...無いですよ(T_T)

たしか、ベータ1の時はあったはず...一応バックアップ
取っておいたので探してみる...ありましたよ。
 /usr/local/pspdev/psp/sdk/doc/html/以下に
ごっそりと(^o^)

おかしいなと思い、PSPSDKをチェックアウトしたディレクトリ
上にあるREADMEを読む...doxygenを使ってヘルプドキュメント
作成してくださいとの事!...ああ、またわけの判らないままに
得体の知れないプロダクトを入れなくてはなら無いのだね(;_;)
...うちのFedraたんがどんどん汚くなっていくよう。

でもってdoxygenですが、よく判りません...必殺、yumコマンド
一発でインスト...れれエラーが、何ぃ、もう入ってますだとう...あ、
確認してなかったよ(^^;)...いや、その、doxygenがドキュメント
生成ツールである事くらいは判りますが...インストールするのに
また色々と...。


...気を取り直してヘルプファイルを生成します。以下参考(^o^)

 PSPSDKをチェックアウトしたディレクトリに移動して
 下記コマンド実行

./configure    <- 必要かどうか判りませんが^^;
make doxygen-doc


  [PSPSDKをチェックアウトしたディレクトリ]/pspsdk/doc/html
   にちゃんとHTMLファイルが出来ます。

  htmlディレクトリ以下をWindowsに持っていけばその中のindex.htm
をブラウザで開けばちゃんと読めます(^o^)

とりあえず、ベータ1のヘルプと比べてみました。鬼のように増えてる
グラフィックスだけじゃないよ(^^;)...凄い遊べるなぁPSPSDK。
頑張りすぎの気がします。

ここをクリックで人気blogランキングへ(ご協力お願いします)

  
 
[PR]
# by pspborder | 2005-07-11 11:41 | PSP開発
すごいです。びっくりです。

PSPで3Dグラフィックスが動きました(^o^)
ばんざーい!(...いや、私が作ったわけじゃ
ないんだけど)

PSPSDK(ベータ1じゃなくて、開発中のやつね)のサンプル
にはGU(PSPのグラフィックスチップの事です)のものも
含まれています。その中に”cube"というのがあります。

この"cube"は6面カラフルな立方体に各面にバンプマップ
(わかんない人はお父さん、お母さんに聞いてみよう)を施した
ものをくるくる回すでものです。

...それが何?っていうなかれ、今までPSPのGUに関しては
ハッキン...いや、調査が進んででおらず、訳の判んないもの
として利用されていませんでした。PSPSDKが出るまでの
プログラミングってビデオラム(VRAM)の先頭アドレスを
取得してそこに、画像データを書き込むという事しかできず
(たいがいそれでいいんですが...)。PSPの無駄に強力な
ハードウエアは利用できなかったんです。これからは、みんな
GUの機能を使ったソフトを作るんだろうなぁ...楽しみです。

で、このサンプル弄んでわかった事書きますね(^o^)

・ テクスチャーに使用される画像ファイルは.ROWファイルです
  フォトショップで編集できるよ(^o^)

・ .ROWファイルはbin2cコマンドでC言語の配列データとして
  変換する事が可能です。サンプルのMakefaile見れば使い方
  わかります。

・ GUに送信するGUアセンブリ(コマンドみたいの)はコマンドリスト
  として事前に用意したコマンドリスト配列変数にGU用のライブラリ
  関数経由でセットします。描画の直前にコマンドリスト変巣はDMA
  転送でGUに送られます。そこで注意なのが、DMA転送に都合の
  よい境界サイズでこのコマンドリスト配列を用意するのがポイント!

・ GUに対して、座標やベクトルの計算を行うためのGE(ジオメトリ
  エンジン)というものがGUとセットでPSPにはありますが、この
  GEに関しては未実装の物があるみたいです。というのはローテ
  ート(回転)などに使う行列の変換...いわゆるジオメトリ演算は
  GEを使わず、C言語のプログラム側でやっています。ま、関数
  用意してくれるからそれを使えばいいんですが、パフォーマンスは
  どうなんでしょうかねぇ?

・ ジオメトリ演算に使うデータの型はfloatが使用されています。
  (多分u32等の整数が必要なライブラリ関数もあると思いますが
   floatが普通に使えるのはありがたいですす。ToolChainの成果
   というのもあるんでしょうが...)

・ cubeで使用される立方体のVertex(頂点情報)はプログラム内に配列
  として用意されています。こんな感じで定義していけば良いんだというのが
  判ります。数少ないからグッドです。但し、数増やしたりサイズ変えるんなら
  Projection(透視変換)とかWorldView(ワールドビュー)とか変える必要
  あるかもです。カメラ固定なんだ、このサンプル。逆にここら辺を変えて
  試してみるのが勉強になりますね。


・ GUの初期化が思いっきりむずいです。画面モードとか変えなければこの
  ままでいけそうですが...。多分、ここら辺は、SCEの純正SDKとかなり
  互換性が確保できている気がします(SCE純正のSDK持ってないので
  あくまで想像ですよ^^;)。
[PR]
# by pspborder | 2005-07-10 00:12 | PSP開発