【雑記】 |
2009/2/28 ブリスル系ブラシ |
テスト実装中だが、品質も維持しようとすると速度条件厳し過ぎ(涙) しかも結局SAIと同じような実装になりそうな予感、、、何か聞こえてきそうな気もするけど何も言うな(笑) 内部的にもブラシエンジンとしては完全に別物になるし、組み込み方どーするかなとか、まだフラットなブラシで使用している計算と一致させる為の考慮が不十分な個所もありもう少し調整を要す. ※) ちなみに先が黒ずんでいるのはテスト用に24bit bmpそのままで描画している為で本実装では消える予定 ;-)
|
2009/2/20 |
今日の教訓、おかしいと思ったら面倒がらずプロットして確かめる事. たかだが10行程度書くだけ、可視化してプロットすればおかしいのは一目瞭然なワケでした、大体パラメータが0になるかなり前に出力が0になる設計は普通はしないワケで、その時点で何か間違っていると気付くべきですとも、ええ X-< まー何やっているか相変わらず意味不明ですが (上のプロットだけで分かる人がいるとしたらそれはそれで凄い) 企業(?)秘密なワケです ;-) --------------- 映画「バック トゥ ザ フューチャー」に出てきたデロリアン、映画の中だけの車かと思ってたのですが、実際に存在する車だった模様、始めて知りました. 別に車に興味あるワケでも無いのですが、フルステンレス剥き出しのヘアライン仕上げのボディは見慣れたツヤツヤの塗装とはかけ離れて金属そのものの重厚感と美しさで素直にカッコイイなぁと思っちゃいます、思わず欲しくなってしまいました(笑) とは言っても古い車なので実際には例え入手できたとしても面倒見だけでも大変そうですが. 以前友人との話題で盛り上がったミツオカのゼロワンなんかもそうなんですが、こういうクセがあるものって例え高くても 「それが欲しい」 という明確な購買意欲をそそりますね. 逆に横に並べて同じように見えるものなら 「少し安いなら別のものでもいーや」 みたいなカンジで、どれだけチマチマした所をブラッシュアップして内部の人間はそれで差別化したつもりでもユーザーから見るとどうでもいい、みたいな事は車だけの話では無く製品開発全般に言える話なんでしょうね、至って当たり前の話なんだけど実際にそれに携わると見失いがちな話、難しい所です ;-) 何が言いたいかって言うとつまり周りの目や競合製品のチェックリストなんか気にしないで馬鹿に見えても楽しけりゃそれが正しいんじゃん、みたいなそんなカンジで、もっとイカれた製品が増えて欲しいものですよね、人間なんて根本的にガキなんですから(ぉ (でもそういうのは関西人的ファッション感覚とかにも通ずるかもね、みたいな) :-P # ボディの持ちの問題もあるんだろうけど、今だからこそ金属剥き出しで表面コーティングのみ、みたいな車出してくれないかなぁ、マジ好みなんだけど. 海外のサイトで見たフルステンレス仕様のランボルギーニとかも塗装車には無い美しさがあったし、あれを見てしまうともうシルバー塗装の車の質感は例えるならプラモデルのメッキ仕上げとパールでシルバーっぽいもの、あるいは本当の金属と絵の具の銀色位の開きがある気がします、それこそラインナップはフルメタルの鏡面仕上げとヘアライン仕上げの2通りとかで、ねぇ(笑)
|
2009/2/12 結局単純な形に落ち着く |
ここ暫くあれやこれやと試してた3Dプロッタの簡易入力機能、結局色々試した末にシンプルなカーソルモデルにする事にした. スクリプトで使用するプロッタという事で余り複雑な機能を計算順序等決め打ちで入れる事も出来ない為、自由度を最大限残すにはこの位が妥当かもしれないという結論に.
機能的には3D空間上をマウスドラッグで動くカーソル機能とスクリプト側からの表示・非表示, カーソル位置取得・設定のみ、実装としてはたかだかスクリプト側からすると関数2つで2週間程色々考えていた事になる、少々非効率 :-< # 余談だが上のソフトのabout表記を見返すと、2004-2009. になっていた、元々が自分の数学的な下地の弱さを補う目的があって作り始めたもの (実際高校までは何とかイメージと理屈が合致した形で掴めてたのだが、大学になって新たに出てきた概念の表すイメージが掴めず数学の単位落としまくった挙句、遊び呆けて卒業「だけ」して、結局社会人になってから代数も微積も勉強し直す羽目になった) それ自体がモチベーションとなった部分もありここ数年随分数値計算や数学の再勉強はやったつもり、5年前に比べれば遥かにマシになっているが、一方で5年でこの程度かと己を責める、或いは忌々しく感じる部分もあり、これは別に数学だけに限らずプログラム全般についても同様、まぁ所詮塵芥の如き身なればできる事をやるだけしか無い(※1)ワケで、ただこうして考えると結構あれから時間が過ぎたなぁというカンジで妙にしみじみ(苦笑) ※1) ともすれば「〜をやりたい」とか「〜できるようになりたい」という言はその後ろに暗黙に「但し正攻法以外で」と付いてしまうのは人の弱さ故に陥りがちな話、ただ別にゲームや漫画の主人公みたいな「選ばれたもの」である筈も無い殆どの人間にとってそんなものはファンタジーやメルヘンでしか無いワケで、結局地味なものを積み重ねてゆく以外の如何なる近道も無いワケであります、だからと言って諦め、あるいは目をそらして鬱屈したストレスとやりきれなさ或いは自己欺瞞を抱えて生きるのも無様だし、行動せずそれを語る事だけを代償行為としてしまうのも同様に (これまた矮小な) プライドが許さぬワケで、結局地味なものを積み重ねて行くしか許されないワケです(※2) ええ、自戒を込めて ;-) ※2) そしてそういう考え方をする人生は「決して幸せになれない」のだそーですけどね(笑) :-P
|
2009/2/8 あれま |
昨日のGetGlyphOutlineの件、実際に以前の改善前の自前エンジンのアルゴリズム (GetGlyphOutlineと同品質程度) と比較してベンチマークを取ってみた所自前エンジンの方が倍近く速かった (GetGlyphOutlineはGGO_GRAY8_BITMAPを使用、自前のものもキャッシュ化とかはしてないので単純な速度比較) APIだしそんなに無駄な事はしてないだろうと思っていただけに少々拍子抜け (^^;; 現状ペイントソフトの方で使っているエンジンは品質改善の為大幅に計算量が増えているので流石に比べるべくも無いが、まぁ無駄にならなかったという所か. ま、実際は最初からGetGlyphOutlineを使って楽してたら今の品質に届かなかったと思うので、別段ネタで話している程後悔はしてないんですけどね、元々KOJIさんのsaiが速度最優先になっているので、こちらは自分の得意分野という事で理論の再現と品質最優先という事なんで ;-) まぁ半ば怪我の功名的ではありますが(苦笑) 、、、いやホント全然悔しがってなんかいないから、マジでマジで、、、まぁ少し位は(ぇ、、、みたいな ;-)
|
2009/2/7 |
まぁそんなワケでAPIによるwavの同時再生は完了、細かい調整はまた使いながらというカンジ. なお最初は無圧縮 11025/22050/44100Hzのwavのみとして周波数変換は自前の変換ルーチンを介していたが、圧縮wavなども含めAPIで簡単に変換できるらしいのでそちらを使う事に. 興味がある人はacmFormatSuggest / acmStreamOpenなどで検索するとちょっと幸せになれるかも ;-) なお上記APIは変換元の形式を示すWAVEFORMATEXへのポインタを受け取るが、無圧縮PCM以外ではここにRIFFのfmtチャンクに含まれる全ての情報を渡さなければならない、圧縮形式などではfmtチャンクはWAVEFORMATEX+付加情報となっているので、acmに渡すWAVEFORMATEXへのポインタはこの付加情報まで含めた領域を指している必要がある. ものの見事に1時間程これでハマる羽目になったのでメモがてらというカンジ. --------------- wave関連を色々調べている時に見つけたのだが、どうもフォントのアンチエイリアスの実装はGetGlyphOutline()というAPIで指定したフォントのアンチエイリアスしたα情報が取得できるらしい、それ以外にも内部フォーマットになるが曲線データとして構成するベクトルポイントも取れるとか、、、って既に自前で作っちゃったよ>アンチエイリアス描画 (T_T) もー少し早く知ってれば、みたいな限りなくやっちゃった感全開な気分 orz まぁ先日自前のエンジンは色々手を入れた事もあって (特に小サイズのフォントなどの) 再現性や描画品質は上のAPIより良かったのはせめてもの救いだが、演算コストも結構馬鹿高い計算をしている個所があるので、品質重視のペイントソフトで使うエンジンは自前のものとしても、他で使うなら標準APIでも良いよーな気がする、なんだかすごくくやしい(笑) のでこーなったら自前エンジンの描画品質をもっと突き詰めるべきか :-< --------------- それ以外にはCreateWindowの親WindowフラグにHWND_MESSAGEなんてのがあるのも今更知ってみたり、体裁の問題で必須機能では無いしWin2k以降なのでまだ暫くは使う予定は無いけど ;-) まーそんなこんなで、ここ暫くの話はAPIこねくり回しているだけなんで面倒な割には大して力になる話でもないです、何かそんなプログラムばかり書いていると欲求不満になりそうな微妙なかったるい感ともやもや感が、、、(苦笑)
|
2009/2/5 単に音(wave)を鳴らしたいだけなのだが |
ここ数日サウンド関連のプログラムでハマる、とは言っても単純にwaveで音を鳴らしたいだけなのだが、今の所こんな具合で推移 1) MCIで取り合えず作る、但し再生ファイルのロード・リロードのタイミングは勝手にMCIが管理する為、場合によってはオーバーヘッドが大きくなる、BGM程度の粒度であれば、MCIの制御を全て別スレッドとしコントロールも可能な限り非同期で行うようにすれば結構いけるが、SEに関してはやはりメモリ常駐でないと辛い. 2) PlaySound / sndPlaySound APIは複数同時再生ができないので論外. 3) waveOutOpen()を使用したら複数再生できる (これには制限があるが後述) ようなので、それで取り合えずwave単位で再生する、多重再生はできたがHWAVEOUTのOpen/Closeで稀に暫く呼び出しがロックするケースがあり、スレッド化しても問題になる位の遅延が解消できない. 4) APIに拘るのを諦めDirectMusicを使う、以前仕様を読んだ時は圧倒的にこちらの方が楽だと思っていたのだが、実際に動かしてみると (マシン・環境依存で一部のマシンだけ) デバイスを上手く占有できないのか頻繁に再生していると エラーも出ず再生されないケースが発生、ゲーム用という事でハードに近い分固有ドライバなどに依存する率も高いのか、汎用APIに比べると (OpenGLなどと同様) 環境による揺らぎに影響される機能といった印象を受ける、これはライブラリとしては余り望ましいものでは無い :-< また (仕様上仕方無いが) MIDIのループ再生では音源がループ時に初期化されない為、前の再生での設定を引きずってしまい正常にループできない場合もある、これもフリー素材などを流用するケースも想定すると、どんなMIDIでも再生できるワケでは無いのは少々難点. また (当然ながら) MCIと併用するのは余り宜しくない (フォーマットの多様性からBGMではMCIは使いたい) 事や、再生の一時停止の実装やリソース管理が少々面倒だったりというのも余り嬉しくない、またCOMで複雑なインスタンス関係を持つライブラリはスレッド間運用が少々制限されがちなのも (ゲーム用途のみで無く汎用目的な) ライブラリの想定ではかなり嫌な所 (ついでに言うと (多分) DirectX関連のライブラリは初期化時に与えるWindowハンドルで示されるWindowの状態とリソース占有管理が一部内部で勝手に相関してるっぽい挙動を示すのもかなり嫌 :-<. 5) ともすればライブラリがクライアント側の書き方や実行モデルを規定してしまいがちになり、犠牲が大きいという事で、気を取り直し再びwaveOutOpen() APIに戻る、予め複数のHWAVEOUTを特定フォーマットで開いておき、音声読み込み時には別途そのフォーマットに自前で変換して空いているポートで連続再生する方法を取る、結果は上々で結構良いカンジ、但し調べてみると1つのデバイスにHWAVEOUTを複数OpenできるのはWin2k以降で9x系はNGとの事. 実際には現状新規のソフトでWin98,Meをサポートするケースはまず想定しない (したくもない;-) が、たかだかwaveの再生という傍流で制約が発生する事や、新設APIならともかく、半ば暗黙のOSの挙動変更に依存するライブラリというのは余り気分の良いものでは無い. 6) 仕方無いので (やりたくなかったが) 単一のHWAVEOUTをOpenして適当な時間 (1/30secとか) 単位でwaveを細切れにしたものを自前で連続キューイングして送信する方法を採用、無音であっても常にデータは流れる状態で、再生音声はリスト化して専用スレッドで複数同時再生用にリアルタイムに波形を合成 (※1) してトリプルバッファで継続的に送信し続ける方法を取る ←今ここ. 実際にやってみると思ったよりは上手く動いている模様、CPUの占有率も余り食っていない (とは言え今時9xが動いているマシンでどうかは別だが). ボリューム設定もwaveOutSet/GetVolumeはPCのマスターボリュームとリンクしているので使うべきでは無いが、こちらの方法なら幾らでもバッファに詰め込む時に波形を加工できる事や、将来的にアナログシンセのエミュレータなど所謂 「音源」 などを作る場合には必須となる (作るかどうか知らんが:-P) 手法である為決して無駄では無い、無駄では無いのだが、、、やっている事が (割り込みかスレッドかの違いはあれど) 10年前と同じような事な気がして少々ゲンナリする、、、たかだか音を同時再生したいだけなのに何でこんなに面倒な事になっているのやら X-< ※1) ここはフォーマットが同じなら単純な波形の加算+飽和演算で良い模様. ただ結果的に同じ音を余り沢山重ねるとディストーション系エフェクタと同じ特性になるのが (余り音周りは詳しくないので) これで良いのか少々気になってはいるが. ※1') X68kならPCM8とかがやっていた処理と似たようなカンジ、ただ今ではマシンパワーが馬鹿みたいに増えたので割と愚直に書いてもそれなりに動いてくれるのが有り難い所、あの時代のマシンスペックで単位時間辺りのPCM合成処理を割り込み周期に間に合う形で完了させるなんて話は正直考えただけでゾッとする(苦笑) --------------- それ以外にはフルスクリーン化などちらほらと、DirectXを使うなら比較的安易にできるのだが、その時点で描画APIの選択肢が固定されてしまう為、現状そういう縛りが入るのは嫌だったのでこちらもAPIでChangeDisplaySettingsを使う、これの注意点は画面切り替えの前後でWindowの位置などを覚えていない為、フルスクリーン化の前後でWindowの位置情報を記憶して復帰してやる必要がある、最近のOSでは直ったという話も見かけたのだが、これも一見正常に動くように見えて状況により復帰されるケースとされないケースがある模様につきやっぱり自前処理. 最初からフルスクリーンかWindowモードのいずれかを選択して起動するだけなら話は簡単なのだが、普通は実行中動的にフルスクリーンとWindowモードは切り替えられるのが当然だろう、という事でこれを実装しようとすると結構泥沼になった. まずハマったのはChangeDisplaySettingsの呼び出し中に発生するWM_SIZEなどのイベントで来るイベント引数のサイズ情報やGetClientRectで取得されるサイズ情報は正確では無いのでこの辺の取得・修正タイミングに注意する必要があるという所、次いでこのディスプレイ解像度の変更で発生するイベントの種類や順序がOSのバージョンごとに微妙に違うので余り決め打ちでアテにできないとこれもまたかなり嫌な話 :-< まぁそれでも何とかそれなりに安定したものは出来たカンジ. 上のwaveの話もだが、ちょっと想定用途を外れると途端に面倒になるのは何とも言い難し.
|