1999年8月のエントリ

Direct3D,Viewport の ForceUpdate で画面が更新されなくて困る。原因は ForceUpdate の 3,4 番目の引数が幅,高さだと思っていたこと。実際はクライアント座標。

DirectDraw カラーキーについて

DirectDraw のカラーキーは,実際のハードウェア,BPP などに対応する値を指定してやる必要がある。1 番確実な方法はサンプルのように,サーフェスに GDI で描画をし,値を読み出すこと。

DWORD CDirectDraw::DDColorMatch(LPDIRECTDRAWSURFACE pSurface, COLORREF rgb)
{
    DWORD result;
    COLORREF oldrgb;

    HDC hdc;

    // GDI を使って色を置く
    if(rgb != CLR_INVALID && pSurface->GetDC(&hdc) != DD_OK)
    {
        return 0;
    }

    // 前の値を保持
    oldrgb = ::GetPixel(hdc, 0, 0);

    // 色を置いてみる
    ::SetPixel(hdc, 0, 0, rgb);

    pSurface->ReleaseDC(hdc);

    // ハードウェア依存の値を読み込む
    DDSURFACEDESC ddsd;
    ddsd.dwSize = sizeof(DDSURFACEDESC);

    HRESULT hres;
    while((hres = pSurface->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
    {
        ;
    }

    if(hres == DD_OK)
    {
        result = *(DWORD *)ddsd.lpSurface;

        // BPP に対する修正
        if(ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
        {
            result &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;
        }

        pSurface->Unlock(NULL);
    }

    // 書き込んだ値を元に戻す
    if(rgb != CLR_INVALID && pSurface->GetDC(&hdc) != DD_OK)
    {
        return 0;
    }

    // 色を置いてみる
    ::SetPixel(hdc, 0, 0, oldrgb);

    pSurface->ReleaseDC(hdc);

    return result;
}

Direct3D,メッシュを見えなくするには,Frame.DeleteVisual すればよいが,メッシュの参照がなくなり,メッシュが削除され,もう 1 度表示するときに困る。これを防ぐには先に Mesh->AddRef() をしてやればよい。

DirectSound で音が鳴り終わったことを検出する為に IDirectSoundNotify を使う。DIRECTSOUNDBUFFER 作成時のフラグに DSBCAPS_CTRLPOSITIONNOTIFY を指定するのを最初忘れた。

DirectSound,弾を撃つバッファを static で作ったが,複数の音が鳴らない。これは別々にバッファを用意するしかないようだ。

DirectInput。GetDeviceData が Release フルスクリーンでうまくいかなかった。原因は第 3 引数が入出力両用ということに気付かず,初期化しないまま渡していたからだ。

SendChatMessage を使うために DirectPlay インターフェースを IDirectPlay3 に。しかしインターフェースがかなり変わっていて戸惑う。

結局 SendChatMessage はロビーを使わないとだめなので使わなかった。

DirectSound が初期化できなかった。原因はサスペンドした時にサウンドカードが使えなくなってたため。もう一度差し直すことで解決。

スタティックライブラリにリソースを埋め込む方法。[挿入] – [リソース] でリソースを作成,その後プロジェクトに *.rc を追加する。

DirectX の簡易ライブラリを作ろうと思う。使いたい DirectX ラッパークラスを継承するというものにしようと思う。


スタティックライブラリの作り方。何度かやってるがいつも迷うのでここに書いておく。新規ワークスペースで Win32 Static Library を選び,プリコンパイル済みヘッダ,MFC サポートを on にする。


DirectSound。DSound.h をインクルードする前に MMSystem.h をインクルードする必要がある。ちなみにライブラリは DSound.lib と WinMM.lib。


Information の r が抜けていた。全部直す。

ILS2 で面白いミス。

if(m_pDDSOffScreen->BltFast(MESSAGE_X, MESSAGE_Y, m_pDDSMessage, CRect(0, 0, MESSAGE_WIDTH, MESSAGE_HEIGHT), DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT) != DD_OK)

m_pFrameScene->Move(D3DVAL(1.0));

のようなことをやって,Move されずに悩んだ。if 文の中身を忘れて次の文が実行されなかったのだ。


クラス情報にアクセスできないとか言われる。対処法は,dsw,dsp を除いて clw などを消せばよい。


Surface の GetDC を使う際,ReleaseDC を忘れて次に呼び出されたときに固まった。よくやるので気を付けねば。


SetOrientation で,回転した場合速度ベクトルが更新されなくて困る。これは一旦絶対座標で速度を 0 にしてから速度を絶対的に設定することで解決。

Direct3D,テクスチャは 2 の n 乗でないと SetTexture でエラーが出るようだ。ていうかそんな制限どっか書いてあったっけ?

テクスチャがどうやってもできないと思ってふと裏から見るとちゃんと見られる。でも何故裏にできる?

ということでよく調べると座標系を勘違いしていた。ヘルプを見てやっと座標系を理解できた。しかしカメラ,ライトは z 方向を向くとかはどこにも書いてないような。試行錯誤でやっと分かってきた。

念のため。SetPosition は自分のフレームの位置をベース座標で指定する。SetOrientation は自分のフレームの向きをベース座標で指定する。その際,第 2 ~ 4 引数は自分の z 軸をベース座標で表した値,第 5 ~ 7 引数は自分の y 軸をベース座標で表した値である。

Direct3D,X ファイルをリソースからロードしようとして失敗する。見つからないと言われる。D3DRMLOADRESOURCE の loadResource.lpName が LPCTSTR なのが不思議に思ったのだが,結局リソース ID を MAKEINTRESOURCE で変換することで解決。

D3DRMLOADRESOURCE loadResource;
loadResource.hModule = AfxGetInstanceHandle();
loadResource.lpName = MAKEINTRESOURCE(RESOURCE_ID);
loadResource.lpType = "X";
pMeshBuilder->Load(&loadResource, NULL, D3DRMLOAD_FROMRESOURCE, NULL, NULL);

VisualC++6.0 の,Doc-View を使わない設定だと,AppWizard で LoadStdProfileSettings が生成されない。ILS2 に以下の部分を追加

LoadStdProfileSettings();

Direct3D の初期化をする。ぷぅさんからテストデータがあがったので試してみたいのだ。しばらくやってると妙に動作が重い。ふと時計を見ると他の時計より 30 分ばかり遅れている。おや? と思って修正しようとすると,明らかに時間が進むのが遅い! ていうか何だコリャ。熱くなりすぎておかしくなったのか? ともあれ時間が遅れるとはビックリ。ちなみに再起動したら直った。

ILS2 を進める。

クライアントウィンドウに対するメインウィンドウの合わせ方

AdjustWindowRectEx を使う。これはあるウィンドウサイズ,あるメニューに対してメインウィンドウをどのくらいにすればよいかを返す関数で,例えば CMainFrame::PreCreateWindow で

CRect rectClient(WINDOW_BASE, WINDOW_BASE, WINDOW_BASE + WINDOW_WIDTH, WINDOW_BASE + WINDOW_HEIGHT);
::AdjustWindowRectEx(&rectClient, cs.style, NULL, cs.dwExStyle);
cs.x = rectClient.left;
cs.y = rectClient.top;
cs.cx = rectClient.Width();
cs.cy = rectClient.Height();

のように使う。


で,ウィンドウモードだが,なかなかうまくいかなかった。原因を調査していると,Primary Surface に BltFast しているのがいけないらしい。Blt ならうまくいく。何故だろう。

ILS2 で使用する Sound ライブラリ。なんとか wav ファイルの再生が完成。これで Direct Sound もいけるだろう。


ウィンドウのサイズを固定にする方法。例えば AppWizard で作ったものなら,

cs.style &= ~(WS_MAXIMIZEBOX | WS_THICKFRAME);

としておけば ok。

Apatch 原因が分かった。ホームディレクトリのディレクトリは最低限 701 でなければ www…/~user/ は読めないらしい。Slackware の時はデフォルトで 755 になってたってことだろう。ちなみに設定ファイルは CGI の部分以外は元に戻しても大丈夫だった。

次は CGI。Slackware の時も起動しなかったが,Turbo でも起動しない。しかしさっきの問題を解決するのに設定ファイルをきちんと勉強したので大丈夫。srm.conf に

AddHandler cgi-script .cgi

と書かれているので .pl ではデフォルトで実行されないのだろう。

AddHandler cgi-script .cgi .pl

として解決。

Apache 状況変わらず。設定ファイルは間違ってないような感じだが…


Denasu System のカウンタを SSI に変える。メインページのファイル名を index.shtml にし,counter.pl を修正。最初日本語を EUC にするのを忘れた。ちなみに拡張子を shtml にしても今まで通り http://www.eva.hi-ho.ne.jp/minoru-f/ で表示される。ちょっと心配してたのでひと安心。

起動しない。どうやら Hi-HO の許す include 方式(私命名)では Content-type がいるらしい。これを付けて再試行。おお。うまくいった。

何故 SSI にしたかというと,HTTP_REFERER をきちんと作用させるためだ。今までの img 方式(同じく私命名。img のソースに CGI を指定する。)では,呼び出し元が Denasu ページなので,HTTP_REFERER が Denasu ページになっていた。これからはやっと他のページが表示されるだろう。ひょっとすると Infoseek からの検索キーワードも分かるかも知れない。ちなみに Pha-jtd 氏のページ のリンクで動作を確認。

Windows での外付けハードディスクがおかしい。書き込み中に
ブルースクリーンになる。なんか Linux を最初のパーティションにしたのが
問題っぽい。仕方がないのでフォーマットして Turbo Linux 再インストール。

再インストール時,初回インストール時に入れてなかった httpd を入れておいた。
これでいろいろできるかな。

Apache の設定。一応 http://Lelie/ で Apatch のページは出てくるものの http://Lelie/~Mortarco/ が出てこない。PHT メッセージボードを参考に Apatch の設定ファイルをいじってもダメ。どうなのか。