• ベストアンサー

DirectDrawによるブレンディングについて

2Dサーフェス上イメージのブレンド処理を サーフェスメモリへの直接アクセスでやってるのですが、 いかんせん遅いです。やっぱZバッファとか使うしか ないですかねえ‥‥使い方あまり知らないんだけど‥‥ 3Dでも構わないんで、ブレンド処理を (可能なら)D3DXで使ったコーティング例なんかメールで 送ってもらえたら有難いです‥‥さすがにムリか(爆)

質問者が選んだベストアンサー

  • ベストアンサー
  • hanimaro
  • ベストアンサー率44% (22/50)
回答No.2

MMX命令自体はインラインアセンブラでいつでも使用できます。(VC6の場合) 命令のリファレンスはインテルのサイトからDL出来ます。 スクリーン全体のアルファブレンドの動的変更と言うことは、 フェードイン・アウトやクロスフェードなんかをしたいんですかね? すごい重いということですが、アルファブレンドをかけるサーフェスを ビデオメモリに取ってませんか? システムメモリにサーフェスを作ることで多少改善されると思うのですが。 現在私が作っているプログラムではP3-700+GeForce2GTS+Win2kのマシンで 640x480の16bitのMMXを使用したクロスフェードで 60fps程度ですね。(まだ高速化の余地はありますが・・・) Celeron366+TNT2+Win98では30fps程度ですが、実際に見てみると特に遅いと思うことはないです。 画面のエフェクト程度ならばこれぐらいで十分だと思いますが。 でも、いくら頑張っても3Dハードウェアを使用するほうが早いです。 3Dハードウェアを使用すると環境が結構限定されてしまうのが欠点ですね。 このサイトに、MMXを使用したアルファブレンドのサンプルがあります。 MMXを使用しない場合でも、かなり最適化されてます。(すごいです) 私も参考にさせて貰いました。 ただ問題なのが英語のページなんです・・・

参考URL:
http://www.gamedev.net/reference/programming/features/mmxblend/page8.asp
fatal-crisis
質問者

お礼

うぅっ、英語なんですね(T-T) けど プログラマって英語力必要ですよね‥‥どうにか頑張ってみます。 サーフェスのメモリ確保も(まだやってないんですけど) 変更して動作確認してみます。これで解決すれば万々歳ですが^^; ではでは、ありがとうございました。 またカキコみつけた時は お願いします(笑)

その他の回答 (1)

  • hanimaro
  • ベストアンサー率44% (22/50)
回答No.1

はじめまして。 サーフェスをLockしてアルファブレンドする場合は アルファブレンドするサーフェスをビデオメモリに取っているのであれば システムメモリに取ると早くなります。 DirectXではビデオメモリのサーフェスへLockして、データをリードすると めちゃめちゃ時間掛かります。(すべての環境で遅いとは限らないかもしれません。今まで見たビデオカードではそうでした。) それと、MMXを使うとさらに高速化が可能です。 MMXを使用すると、16ビットカラーの場合4ピクセルずつ処理できます。 ビデオカードが対応していればD3DXを使用した方が高速です。 ただ、ビデオカードが対応してなければやはり遅いです。 D3DXで半透明はDirectXのサンプル見れば簡単に作れるのでは? 俺はIMでしかやったこと無いですが・・・ 参考になれば幸いです。それでは。

fatal-crisis
質問者

補足

回答ありがとうございます。 今ブレンドで処理したいのが、 スクリーン全体のブレンドによる動的変更―― つまり連続(アルファ値を徐々に変更)した ブレンド処理なんですけど‥‥それやろうとすると、 やはり2Dではどーしても重いんですね。 普通にブレンド使う分には全然おっけーなのですが。 MMX指令は、ちょっと知らない部分かも‥‥ でもあれってIMとかで使うんですよね・・・・やっぱ3D使うかなあ‥‥

関連するQ&A

  • 未解決の外部シンボル

    Microsoft DirectX SDK (August 2009)\Samples\C++\Direct3\MultiAnimationをデスクトップにコピーして実行すると動くんですが、SampleBrowserからemptyprojectをインストールして MultiAnimationと同じcppとhをプロジェクトに追加すると、 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateEffectFromMemory@56 が関数 "public: long __thiscall CDXUTDialogResourceManager::OnD3D10CreateDevice(struct ID3D10Device *)" (?OnD3D10CreateDevice@CDXUTDialogResourceManager@@QAEJPAUID3D10Device@@@Z) で参照されました。 1>DXUTcamera.obj : error LNK2001: 外部シンボル "_D3DX10CreateEffectFromMemory@56" は未解決です。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateSprite@12 が関数 "public: long __thiscall CDXUTDialogResourceManager::OnD3D10ResizedSwapChain(struct ID3D10Device *,struct DXGI_SURFACE_DESC const *)" (?OnD3D10ResizedSwapChain@CDXUTDialogResourceManager@@QAEJPAUID3D10Device@@PBUDXGI_SURFACE_DESC@@@Z) で参照されました。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateFontW@48 が関数 "protected: long __thiscall CDXUTDialogResourceManager::CreateFont10(unsigned int)" (?CreateFont10@CDXUTDialogResourceManager@@IAEJI@Z) で参照されました。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateTextureFromFileW@24 が関数 "protected: long __thiscall CDXUTDialogResourceManager::CreateTexture10(unsigned int)" (?CreateTexture10@CDXUTDialogResourceManager@@IAEJI@Z) で参照されました。 1>SDKmisc.obj : error LNK2001: 外部シンボル "_D3DX10CreateTextureFromFileW@24" は未解決です。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10GetImageInfoFromFileW@16 が関数 "protected: long __thiscall CDXUTDialogResourceManager::CreateTexture10(unsigned int)" (?CreateTexture10@CDXUTDialogResourceManager@@IAEJI@Z) で参照されました。 1>SDKmisc.obj : error LNK2001: 外部シンボル "_D3DX10GetImageInfoFromFileW@16" は未解決です。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateTextureFromResourceW@28 が関数 "protected: long __thiscall CDXUTDialogResourceManager::CreateTexture10(unsigned int)" (?CreateTexture10@CDXUTDialogResourceManager@@IAEJI@Z) で参照されました。 1>DXUTgui.obj : error LNK2019: 未解決の外部シンボル _D3DX10GetImageInfoFromResourceW@20 が関数 "protected: long __thiscall CDXUTDialogResourceManager::CreateTexture10(unsigned int)" (?CreateTexture10@CDXUTDialogResourceManager@@IAEJI@Z) で参照されました。 1>DXUTres.obj : error LNK2019: 未解決の外部シンボル _D3DX10CreateTextureFromMemory@28 が 関数 "long __stdcall DXUTCreateGUITextureFromInternalArray10(struct ID3D10Device *,struct ID3D10Texture2D * *,struct D3DX10_IMAGE_INFO *)" (?DXUTCreateGUITextureFromInternalArray10@@YGJPAUID3D10Device@@PAPAUID3D10Texture2D@@PAUD3DX10_IMAGE_INFO@@@Z) で参照されました。 1>DXUTres.obj : error LNK2019: 未解決の外部シンボル _D3DX10GetImageInfoFromMemory@20 が関数 "long __stdcall DXUTCreateGUITextureFromInternalArray10(struct ID3D10Device *,struct ID3D10Texture2D * *,struct D3DX10_IMAGE_INFO *)" (?DXUTCreateGUITextureFromInternalArray10@@YGJPAUID3D10Device@@PAPAUID3D10Texture2D@@PAUD3DX10_IMAGE_INFO@@@Z) で参照されました。 1>Debug\GRAVITY ESCAPE.exe : fatal error LNK1120: 外部参照 9 が未解決です。 とでます(長くてすみません)。 追加のインクルードディレクトリにはDXUT\Optional;DXUT\Coreを指定しています。 独学で勉強しているんですが、このエラーの原因がまったく分かりません。 どなたかよろしくお願いします。

  • 複素積分 ∫[-∞→∞] (sinx)/x dxについて

    ∫[-∞→∞] (sinx)/x dx=π について教科書の解説を見ても理解出来ないところがあったので教えてください。 手持ちの教科書では次のような流れで計算をしていました F(z)=exp(iz)/zとおく F(z)はz=0に1位の極を持つのでz=0を避けるような経路C(添付図)をとる … (1) D2は半径εの半円弧である F(z)はCで正則なので∫[C] F(z)dz = 0 … (A) F(z)の経路C=R+U+L+D1+D2+D3においてR,U,Lでの積分は0(証明長くなるので省略) また、D2での積分は ∫[D2] F(z) dz = ∫[D2] {F(z)-(1/z)} dz +∫[D2] (1/z) dz と分けるとF(z)-(1/z)はz=0で正則なのでε→0のとき積分の値は0 … (2) ∫[D2] (1/z) dz は z=εexp(iθ)とおいて計算すると-πiになる (A)でX,Y→∞ ε→0とすると ∫[-∞→∞] (exp(ix)/x dx - πi =0 …(B) exp(ix)=cos(x)+isin(x)より、 ∫[-∞→∞] (cosx)/x dx + i∫[-∞→∞] (sinx)/x dx = πi 両辺の虚部をとって 虚部をとって∫[-∞→∞] (sinx)/x dx=π ここまでが教科書での解答の大まかな流れです 疑問点は以下のとおりです A:(1)で0を避けた理由 B:(2)でF(z)=F(z)-(1/z)+(1/z)と分けたのはどこから来たのか C:(2)でF(z)-(1/z)はz=0で正則とあるがz=0で1/zは定義できないのに正則? D:D1とD3は回答中で触れてないが無視していいのか E:この問題はタイトルの積分を留数定理で解けという問題だったのですが留数定理使ってないような? 長くなりましたがよろしくお願いします

  • DirectXにおける2Dと3Dの座標の違い

    DirectXを使ったプログラミングの初心者で、Softbank Creativeの「シューティングゲームプログラミング」を使って勉強しています。 ライブラリの内容も関わってくるので少し分かりづらい質問ですが、2Dと3Dとで座標の指定の仕方が違うのがよく分かりません。 3Dでは、 D3DXMATRIX mat_view; D3DXVECTOR3 vec_from=D3DXVECTOR3(0, 100, 0); D3DXVECTOR3 vec_lookat=D3DXVECTOR3(0, 0, 0); D3DXVECTOR3 vec_up=D3DXVECTOR3(0, 0, 1); D3DXMatrixLookAtLH(&mat_view, &vec_from, &vec_lookat, &vec_up); device->SetTransform(D3DTS_VIEW, &mat_view); D3DXMatrixOrthoLH(&mat_proj, 120, 90, 1, 1000); device->SetTransform(D3DTS_PROJECTION, &mat_proj); Graphics->SetLight(0, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, -1.0f, 1000); このあたりでカメラを設定し、画面端のx座標が±0.6になる……といったことを決めていましたが、 2Dでは VERTEX vertex[4]={ {x, y, z, 1, diffuse, u, v}, {x, y+dy, z, 1, diffuse, u, v+dv}, {x+dx, y, z, 1, diffuse, u+du, v}, {x+dx, y+dy, z, 1, diffuse, u+du, v+dv} }; device->SetFVF(D3DFVF_VERTEX); device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, vertex, sizeof(VERTEX)); 例えば四角形ポリゴンを描くときにこんな風に記述して、 このx,yにはウィンドウの座標が入っています。 SETFVFでD3DFVF_XYZRHWを設定することで直接2Dに持ってこれる、というようなことが調べて分かったのですが、 三角形ポリゴンにテクスチャを貼り付けて2Dのような表現をする場合、必ずこのようにウィンドウに合わせた座標になる(する?)のでしょうか? つまり、3Dの時のように左端がx=-0.6……というような座標系で表現できないのでしょうか? 書籍には3Dから2Dに変換する式などがありましたが、このような変換をいちいち行わなくても最初から3Dの座標に2Dのものを表示できないのでしょうか? なにぶん初心者で見当外れのことを言っているかも知れませんが、ご教授をお願いいたします。

  • Visual Studio2008でのメモリリーク

    プログラムを組んでいて、終了すると 以下のようなメモリリークがでました。 desktop\emptyproject ?d?a?E?μ\dxut\core\dxut.cpp(3385): DXUTCleanup3DEnvironment hr=DXUTERR_NONZEROREFCOUNT (0x80040904) D3DX: MEMORY LEAKS DETECTED: 363 allocations unfreed (322368 bytes) D3DX: Set    HKLM\Software\Microsoft\Direct3D\D3DXBreakOnAllocId=0x1a35 to debug MSDNでは DXUTERR_NONZEROREFCOUNT Direct3D デバイスがゼロ以外のリファレンス カウントを持っているため、一部のオブジェクトが解放されませんでした。 とありますが、この意味もよく分かりません。 今までのメモリリークは Dumping objects -> {343} normal block at 0x0207F288, 2240 bytes long. のように割り当てられたブロックが分かりましたが、 上の様なメモリリークは初めてで、 文からメモリリークの原因を検出することができないでいます。 何故、下ではなく上の様なエラー文になるんでしょうか?

  • DirectX 11のConsntanBuffer

    DirectX 11 ConsntanBufferの更新について マルチスレッドでConsntanBufferの更新を行うときにエラーが出てしまいます。 基本的な設計ですが、 1. メインのシーケンスを行うスレッド 2.DeviceContextに描画コマンドを詰むスレッド のスレッド2本構成です。 1から2へのスレッドへは仮想的な描画コマンドを発行し、 ダブルバッファリングを行い並列性を高めています。 # よくある方式だと思います。 HLSLで簡単なシェーダを作りポリゴンを表示することはできたのですが、 DirectXをDebugモードで実行すると以下のようなエラーが出てしまいました。 D3D11: CORRUPTION: ID3D11DeviceContext::Map: Two threads were found to be executing functions associated with the same Device at the same time. This will cause corruption of memory. Appropriate thread synchronization needs to occur external to the Direct3D API. 3516 and 5376 are the implicated thread ids. [ MISCELLANEOUS CORRUPTION #28: CORRUPTED_MULTITHREADING ] 内容はスレッド間で同じバッファに対してID3D11DeviceContext::Mapを実行しているため、 中身が破壊される可能性があるというものです。 先述の通り、基本的にDeviceContextを取り扱うのは2のスレッドです。 しかし、内容が動的に変更されるバッファについては 1のスレッドでID3D11DeviceContext::Mapを実行し、 取得したアドレスを直接書き換えるようにしています。 エラーではID3D11DeviceContext::Mapが2つのスレッドで実行されているというのですが、 初期化時は別として、通常のアップデート処理を行っている間は1のスレッドでしか使っていません。 書き込み先のバッファもダブルバッファ化しており、 またCPUAccess / USAGE / BIND / MAPのフラグも D3D11_CPU_ACCESS_WRITE / D3D11_USAGE_DYNAMIC / D3D11_BIND_CONSTANT_BUFFER / D3D11_MAP_WRITE_DISCARD と、動的バッファを使うときの標準的な組み合わせで使用しています。 いろいろとサンプルプログラムを見ているのですが、 出回っているのは大抵がシングルスレッドで作られており、 今回の件に関してはあまり参考になりませんでした。 プログラム中ID3D11DeviceContext::Mapを呼び出しているところは かなり限定できるため、おそらく間違いないありません。 いろいろ調べては見たのですがエラーが出てしまう原因が特定できずに困っています。 エラーの解決方法をご存知の方はいらっしゃいますでしょうか? ■補則 D3D11_MAP_WRITE_DISCARDはCPUとGPUの同期を制御するフラグですので、 CPUとCPUの競合がおきている今回の件とは別のはずです。 他にはID3D11DeviceContextのメソッド中の何かが 内部でID3D11DeviceContext::Mapを呼び出している可能性がありそうです。 2のスレッドで問題のバッファにアクセスしているメソッドは ID3D11DeviceContext::VSSetConstantBuffersぐらいです。 (これが内部でMapを呼び出しているとは思えませんが…)

  • エクセルマクロ 異なる変数でのループ

    エクセルマクロのループ処理に関して、 異なった変数を使いループをさせたいです。 例えばA~Dまでの変数があり、変数Zに順々に変数を代入して処理をさせたいです。 ループ開始 Z = [A-D] (変数Zを使う処理) ループ終了(繰り返し) 1回目にA 2回目にB ・ ・ といったイメージです。 初歩的な質問で恐れ入ります。 よろしくお願いします。

  • Excel整形処理:列ごと&12行おきに「行列を入れ替えて貼り付け」

    ExcelデータをVBAで次のように処理したいのですが、ご助力いただけますでしょうか。 Sheet1のD列とE列に4万行ほどの数値データがあります(行数は必ず12で割り切れます)。 このデータを、列ごと&12行おきに「行列を入れ替えて貼り付け」みたいなことをSheet2に 施したいです。具体的なイメージとしては、 【処理前】 D列 E列 ---------- D1 E1 D2 E2 D3 E3 :(略) D35 E35 D36 E36 :(略) 【処理後】 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 E1 E2 E3 E4 E5 E6 E7 E8 E9 E10 E11 E12■ここで改行 D13 D14 D15 D16 D17 D18 D19 D20 D21 D22 D23 D24 E13 E14 E15 E16 E17 E18 E19 E20 E21 E22 E23 E24■ここで改行 D25 D26 D27 D28 D29 D30 D31 D32 D33 D34 D35 D36 E25 E26 E27 E28 E29 E30 E31 E32 E33 E34 E35 E36■ここで改行 :(略) なお、テキストエディタを介することによってなら、解決策が見つかりました。 (1) E列の右(=F列)に12行ごとに@などの目印をつけます。 (2) E列、F列を選択・コピーし、テキストエディタに貼りつけます。 (3) 置換でまず\nを全て除去し、次にもう一度置換で\t@を\nに。 (4) D列も同様の手順です。

  • ネットワークドライブに繋がらない

    あるパソコンから別のパソコンのHDドライブにネットワーク経由で接続できなくなって大変困っております。現在の状況をまとめますと、次のようになります。 ・全部でA、B、C、Dの4つのパソコンがあり、それぞれにグローバルIPを与えている。 ・Aの中のあるフォルダ(Zとする)を共有にして、ネットワーク経由でB、C、DのパソコンからZにアクセスできるようにしている。 ・先日、突然BからZにアクセスできなくなった。 ・C、Dはこれまで通りZにアクセスできている。 ・BからZにアクセスしようとすると、「\\AのIPアドレス\Zの共有フォルダ名 は見つかりません」と言われる。 ・Bから、「ping AのIPアドレス」をすると正常に認識している。 ・A、B共に設定は変えていない。 ・A、B共にファイアーウォールを切断しても繋がらない。 ・BからC、Dにも同様にアクセスできない。 ・BのパソコンでWebページ等は通常通り閲覧できる。 ・A、B共に再起動してもダメ。 ・NetBIOS over TCP/IPを有効にしてもダメ。 という状況です。 Bでインターネットはできるのに、他のパソコンに直接はアクセスできないという状況の様です。 再びBからA(Z)にアクセス出来るようにするにはどうしたらよいかお教えいただけないでしょうか?

  • 数学

    xyz空間において、xz平面上で曲線C1:z=sinx(0≦x≦π)とx軸で囲まれた図形をD1とし、yz平面上で曲線C2:z=sin^y(0≦y≦π)とy軸で囲まれた図形をD2とする。またtが0≦t≦πの範囲を変化するとき、2点P1(t,0,sint),P2(0,t,sin^2t)を結ぶ線分P1P2が動いて描く曲面をD3とする。図形D1、D2、曲面D3、xy平面の4つで囲まれる立体図形Kの体積Vをもとめよ。 (解) x=y=tで立体図形をz軸に平行なるように切ってできた平面の面積は  1/2・√2・t(sint+sin^2t)=√2/2{tsint+(1-cos2)/2} よって求める体積は V=√2/2∫(0→π){tsint+(1-cos2)/2}dx =√2/2[-tcost+sint;1/4t^2-1/2tsin2t-1/4cos2t]0→π =√2/2(π^2/4+π-5/4) と考えたのですが、間違っていないでしょうか?

  • 3DCGとそのレンダリングについて

    最近3Dがゲームの世界でも主流になってきていますが 私も簡単なスクリプト言語で3Dゲームは組んだことはありますがレンダリングは1つの命令で済みますし、モデリングもソフトがありますし、根本的な仕組みについてはしらないのです。 なのでいろいろ質問させてください まず3DCGに用いられるポリゴン(?)を前提として質問します これって(x,y,z)座標を持った最低3点で1面が形成されるんですよね? それがたくさん集まって1つのモデルができるんですよね? レンダリングについてですが zバッファー方式やスキャンライン方式やレイトレーシング方式 いろいろありますが仕組みはなんとなくわかるんですが なんていうんでしょうか、そのレンダリングの処理の流れがよくわからにのですが 最終的には1枚のポリゴンをレンダリングするプログラムを作ってみたいのですが・・・ 何をどう学べばいいのかわからないのです

専門家に質問してみよう