したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |
レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。

技術情報交換スレ

1管理人★:2004/06/16(水) 20:44
RTXのみならずROや支援ツール全般に関する技術的な情報を交換するスレです。
コーディングに詰まった作者が他力本願的に知恵を増やす目的で設立されましたが、
それだけでなく広く情報交換に使っていただけることを願っています。

管理人の手持ちの情報は少ないですが、RTX/RoTimerの内部動作に関する
御質問などでしたら、できるだけお答えしたいと思います。

規約云々や解析手法の是非などは別スレ/別BBSへ誘導のこと。
水面下に落ちるまではsage縛りで。

2Mystle </b><font color=#FF0000>(M.B.S.4s)</font><b>:2004/06/16(水) 21:51
とりあえず >>1 からネタ振り

21f→21g/h で発生した「特定の環境でタイマーがガクブル問題」ですが、とりあえず
原因となる箇所は判明しました。
DX乗っ取りで実際に書き込みを行うタイミングを変更したのが原因だったようです。

○21f
 2D書き込み:
  窓モードでは DirectDrawSurface->Blt() 、フルスクでは Flip() のタイミングで
  GetDC() してGDIでプライマリサーフェスに直接描画、あるいは自前サーフェスからBlt()
 3D書き込み:
  Direct3DDevice->EndScene() のタイミングで DrawPrimitive() などを投下
  
○21g/h
 3D書き込み:
  EndScene() で (21fと同じ)
 2D書き込み:
  EndScene() で 3D書き込みを行った後に保存しておいたプライマリサーフェスの
  ポインタを使って GetDC() して以下略

というわけで 2D書き込みのタイミングを3Dのそれと一本化したのがまずかったようで。
これがどうしてまずいのかは不明です。

3人柱さん:2004/06/16(水) 23:05
>>2
 
> ○21g/h
> 2D書き込み:
>  EndScene() で 3D書き込みを行った後に保存しておいたプライマリサーフェスの
>  ポインタを使って GetDC() して以下略

EndSceneが非同期で動いてると、その後GDI処理するためにレンダリング終了
まで待つ必要があってRO本体の足を引っ張ってるってことはないでしょうか?

EndSceneでプライマリサーフェイスに書き込んでもFlipかBltでなかったことにな
りませんっけ?バックバッファーに書き込んでるのでしたら、サーフェイスが
VRAM上にあった場合には、GetDCやGDIでほげほげするときにシステムメモリと
VRAM間で転送しまくってて遅い可能性も。

DirectX5〜7ぐらいの期間しかDirectXさわってなかったので、記憶違いだっ
たらすみません。それに、プロファイルとったわけでもないので全部予想に
過ぎません。

4Mystle </b><font color=#FF0000>(M.B.S.4s)</font><b>:2004/06/16(水) 23:55
>>3
21g/h ではこんなふうに書いてたわけですが

// フックした Direct3DDevice->EndScene() 関数
HRESULT WINAPI Nisemono_EndScene(LPDIRECT3DDEVICE7 *lpD3DDevice)
{
  HRESULT hRes1, hRes2;
  hDC hDC;
  
  /*
  // 色々と3Dなお絵かき
  lpD3DDevice->SetRenderState();
  lpD3DDevice->SetTexture();
  lpD3DDevice->DrawPrimitive();
  */
  
  // 本物を呼び出し (ここで3D命令がグラボに飛ぶの?)
  hRes1 = Honmono_EndScene(lpD3DDevice);
  
  // プライマリサーフェス (LPDIRECTDRAWSURFACE7 lpPrimarySurface) は
  // 別箇所 (CreateSurface()のフック関数) で取得・保持しています
  if (lpPrimarySurface)
  {
    hRes2 = lpPrimarySurface->lpVtbl->GetDC(lpPrimarySurface, &hDC);
    
    if (hRes2 == S_OK)
    {
      /*
      // 色々と2Dなお絵かき
      TextOut();
      Ellipse();
      */
      
      lpPrimarySurface->lpVtbl->ReleaseDC(lpPrimarySurface, hDC);
    }
  }
  return hRes1;
}

*lpD3DDevice自体はプライマリサーフェイスから生成されてますから、Honmono_Endscene() を
呼ぶ前に2D描画を試みてもGetDC()自体が成功しません。でこんな順序に。
でもこれだとガクブルするということで

21fでは if (lpPrimarySurface) { ... } のブロックがそっくり 偽Blt() の中にありまして、
Nisemono_EndScene() はRTXの3D描画を終えた後すみやかに
  return Honmono_EndScene(lpD3DDevice);
してますた。これだとガクブルしない、と

5人柱さん:2004/06/17(木) 00:50
http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/jpdx8_c/hh/directx8_c/_dx_d3dcaps8_graphics.asp
を見ると

一般的には、BeginScene と EndScene のペアの外側で 2D 処理を実行する
ことを推奨する。2D 処理がBeginScene と EndScene のペアの間で実行される
場合は、D3DCAPS2_NO2DDURING3DSCENE 能力をチェックする必要がある。この
能力が設定されている場合、アプリケーションでは、BeginScene と EndScene
の間にある 2D 処理は破棄されると考えなければならない。

とあるので、GetDCが成功しないのはそういうことなんじゃないのでしょうか?


ところで、ゲームの一般的な処理って

入力読んだりネットワーク通信したりいろいろ情報更新
BeginScene
DrawXXXなんかで描画
EndScene←ここでバックバッファーに画面が作られる
Flip/Blt←ここでバックバッファーからプライマリサーフェイスに転送
適当にSleep

の繰り返しですよね。だとするとEndSceneの直後にプライマリサーフェイスに
いろいろお絵かきしても無駄じゃありませんか?

##なんか私がどっか勘違いしてる気がしてきた。




掲示板管理者へ連絡 無料レンタル掲示板