スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Xファイルを読み込むときの注意点!その2!

【リンク】 ◆解説系TOP◆

卒業研究はVBを使って開発しているのですが、
間違って無限ループを書いたところ、作業中のデータが全て消えました。

あぁぁあああ"あ"---!! (´;ω;`)

開発環境ごと異常終了するとは何事か!
(VisualStdioならもっと頑張ってくれるのに・・・。)

【教訓】
※1 VBでは、無限ループなどにならないようにしましょう。
※2 こまめに上書き保存しておきましょう。


---------------------------------------------------------------------------
まぁ、その話は置いといて、
今日はXファイルを読み込むときの注意点その2です。

この前は、四角ポリゴンの罠について説明しました。
今回は頂点色の読み込みについてです。

まず、頂点色はXファイル上ではこんな感じで定義されてます。

【参考画像】
頂点色
一番上の数字が頂点色の数
その後は
-----------------------------------------------------------------------
頂点色の番号、 透過度
-----------------------------------------------------------------------
となっています。

なので、こんな感じで色を変えられます。
-----------------------------------------------------
1.000000,1.000000,0.000000,1.000000 //黄色・不透明
1.000000,0.000000,1.000000,1.000000 //紫色・不透明
1.000000,0.000000,0.000000,0.500000 //赤色半透明

-----------------------------------------------------

で、この情報をどう読み込ませればいいのか?と思いますが、
これはDWORD型(unsigned long型)の変数に入れます。

全部で4種類の情報(赤・青・緑・透過度)があるのに、
どうやって変数ひとつに収めるのか?


と思うかもしれませんが、これはビット演算で うまく ひとつの変数にねじりこみます。


DWORD型の変数は4バイト(32ビット)です。
なので、一つの情報につき1バイトずつ使ってひとつの情報とします。

【参考画像】(クリックで拡大)
DWORD内部

そして、1バイト(8ビット)とはどういう事か?というと、
0~255まで表せるという事です。
(符号なしの場合)

「赤」の場合は、下記の様になります。
-----------------------------------------------------------------
255 ←-------    -------→ 0
真っ赤                黒(赤の成分なし)

-----------------------------------------------------------------

ここで一つ目の注意点。
上記のXファイルの画像を見ても分かるとおり、
Xファイル内では、0~1の範囲でしか値を表現しません。

なので、値を全て255倍する必要があります。
--------------------------------------------------
1.0(最大値) ― 255倍 → 255(最大値)
0.5(半分)  ― 255倍 → 127(半分)
0.0(最小値) ― 255倍 → 0(最小値)

--------------------------------------------------
※小数点以下は切り捨て


そして、もう一つの注意点。
1バイトずつ使って値を入れると言いましたが、
具体的に、どこにどの情報が入るのか?というと、

左から順に 透過度となります。

気付いた人が居るかもしれませんが、
-------------------------------
Xファイルでは、左から  透過度
DWORD内では、左から  透過度

-------------------------------
「透過度」の情報が、 なんか調子に乗って一番左に来ています。

つまり、
Xファイルの並びとDWORD内部の並びは
一致しておりません。

※間違ってXファイルから「赤」の情報を、DWORDの「透過度」の所に入れないようにしましょう。

これら2つの問題点を考慮すると、

【赤の情報】  255倍して、 16ビットシフト。
【緑の情報】  255倍して、 8ビットシフト。
【青の情報】  255倍して、 そのまま値を入れる。
【透過度の情報】  255倍して、 24ビットシフト。

こうなります。

プログラムだとこんな感じ。
-----------------------------
DWORD tD = 0;
float a,r,g,b;

r = GetFloatValue(); //赤
g = GetFloatValue(); //緑
b = GetFloatValue(); //青
a = GetFloatValue(); //透過度

tD = 0;
tD += ((int)(r*255))<<16;
tD += ((int)(g*255))<<8;
tD += ((int)(b*255));
tD += ((int)(a*255))<<24;

-----------------------------
※GetFloatValue()というのは、ファイル中の数字の文字列
符号付き浮動小数点数の値に変換する関数です。勝手に作りました。

で、代入した後ちゃんと値が入っているのかも調べたいと思うはずです。
しかし、コレ、簡単には調べられないんですよ。
(もしかしたら、調べる方法があるかもしれませんが)

で、何故調べられないか?というと
値を見てみても、 4294967295とか
とてつもない大きさの10進数で表記されるんですよ。

こんなの見ても、正しい値が入っているのか分からん。

こういうのは11111111000000001111111100000000みたいに
2進数で表記して欲しい ところです。

なので、2進数で表記させるプログラムも作ってしまいましょう。
難しそうに思えますが、実はそれほど難しくはないです。
------------------------------
printf("Color = ");
for(int j = 0; j < 32; j++){
printf("%d", (Color>>(31 - j))&1);
}
puts(" ");
------------------------------
プログラムとしてはこれだけでOK。

↓こんな流れです。
----------------------------------------------
右に31ビットシフトして、1と論理積をとった結果を表示
右に30ビットシフトして、1と論理積をとった結果を表示
右に29ビットシフトして、1と論理積をとった結果を表示
右に28ビットシフトして、1と論理積をとった結果を表示
        :
        :
右に1ビットシフトして、1と論理積をとった結果を表示
なにもせずに、そのまま1と論理積をとった結果を表示
最後に改行

----------------------------------------------

そして、下の画像が実行結果です。
※Colorは変数ではなく配列になっています
Color2進数

【追記】
16進数表記版も作りました。
-------------------------------------

DWORD temp = 0xff00ff00;
char* t = "0123456789ABCDEF";

printf("Color = ");
for(int i = 0; i < 32; i += 4)
{
   printf("%c",t[(temp>>(28 - i)) & 0xf]);
}
puts(" ");
-------------------------------------
それぞれシフトした後、16進数のfと論理積をとります
(10進数で15、2進数で1111

0xf と論理積を取れば、必ず0~15までの値になるのであとはそれを添え字番号として使って
表示させます。
同じく、プログラムとしては案外短く書けます。

今日のおさらい!
-------------------------------------------------------------------
【1】頂点色情報はDWORD型に入れてひとつの変数として表現する。
【2】情報の最小・最大値は、Xファイルでは0~1、DWORD内部では0~255の範囲。
【2】「透過色」の情報が、DWORD内部では調子乗って一番左に来ているので、
   シフトする場所に気をつける。

-------------------------------------------------------------------

これで、自力でXファイルを読み込もうとする時の苦労が減るはず!
ではでは(`・ω・´)ノシ
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

No title

※2 こまめに上書き保存しておきましょう。

無意識にCtrl+S(保存)を押す癖がついていて、Ctrl+Sを押しては、そういえば何のショートカットを実行したんだ・・・?と日々疑問に感じたりしています。

No title

2進数より 16進数の方が見やすくないですか?

No title

>>cさん
そうなのですかe-451
無意識の内に癖がついていると、 忘れる事もなくて便利ですねv-290

時と場合によっては、それで困ったりすることもありそうなので、
注意も必要ですねv-293

自分は、「上書き保存をしますか?」とメッセージが表示された場合
とにかく上書き保存する癖がついているので、不必要なファイルの修正、変更をしてしまった場合でも
上書き保存してしまって困った事がありました。
-------------------------------------------------
【1】Test.txtを何故か2つ開く (A,Bとする)
【2】Aの方を色々と修正、保存。
【3】Bを消そうとした時に、上書きしますか?と聞かれる。
【4】間違って上書きする
【5】修正したAが消えて、Bが上書きされる。

-------------------------------------------------

No title

>>Justyさん
確かに、16進数の方が短くなりますし、
そっちの方が良さそうですね。v-293
「確認できればいいや」と思っていたので、単純な方法を取ってました。
(0か1の値を入れれば、とりあえず正しい値が入っているかどうかは分かる)

16進数の方が分かりやすそう&見やすそうなので、
本文の方に 16進数表記版も書き足してみましたv-290
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。