プログラミングメモ

聖根のアジト / メモ / プログラミングメモ



DirectX8におけるスクリーンショット

以前、DirectX7で作っていたゲームの一つのグラフィック部分をDirectX9へ移行した。
しかし、DirectX9では最新の環境では追加のランタイムをインストールする必要があり、それがまた少々探し辛いため、追加ランタイムが不要となるDirectX8へグレードダウンした。
(DirectX12へ乗り換える予定もあり、少々勉強もしたが、DirectX12でやりたいことも特に無いし、また大掛かりな改修が必要になりそうだし、Windows10未満を互換切りするのにも抵抗を感じたため、結局DirectX8となった)
その際に問題となった事が一つあった。

それは、IDirect3DSurface8にはGetDCメソッドもGetRenderTargetDataメソッドも存在せず、スクリーンショットが取れないことである。
ウインドウに対してGetDCを用いることで、スクリーンショットをとることはできるが、ウインドウによる伸縮の影響は受けてしまう。
ウインドウサイズが固定であればそれでも問題にならないだろうが、環境による解像度の違いもあり、ウインドウサイズは任意に変えられるようにしたい。

DirectX8.1であれば、D3DXSaveSurfaceToFileを用いることで、ファイルへの保存はできるらしいが、使ってるのはDirectX8.0なのと、やりたいのはクリップボードへのコピーなので、ひとまずスルーした。

対策として、結論から言うと、CreateImageSurfaceCopyRectsを使えば実現できた。
まず、CreateImageSurfaceで作成したサーフェスに対し、レンダーターゲットとなっているサーフェスから、CopyRectsで内容をコピーする。
後は、LockRectでサーフェスをロックしてビットデータを取り出し、SetDIBitsでビットマップデータにそれを書き込めば良い。
注意点として、CopyRectsは環境によっては、コピー元とコピー先の色の形式だけでなく、サイズも一致していないと、エラーナンバー「0x8876086c」により失敗してしまう(pSourceRectsArray等を指定しても同じ)。

他、GetFrontBufferというのもあるが、これは画面全体のスクリーンショットとなり、サーフェスの内容をコピーできるわけではない。
スクショの結果がモノクロになってしまうという現象にも悩まされたが、それは単なる演算子の優先順位を見落としてたことによるミスだった。

2025.11.2


JOINについてのあれこれ

SQL言語のJOINには、INNER JOIN、LEFT (OUTER) JOIN、RIGHT (OUTER) JOIN、FULL (OUTER) JOIN、CROSS JOINがある。
LEFT JOIN、RIGHT JOIN、FULL JOINは、まとめてOUTER JOINと呼ばれる。

ここで、INNER JOINとOUTER JOINは対義のような名前になっているが、かなり性質の違うものだと思う。

INNER JOINは、結合先で条件に合うレコードの組がn個あれば、シンプルにn個のレコードが結果に追加される。0個ならば何も追加されない。
対してLEFT JOINは、n>0ならばn個、n=0ならば片方の分が空白となっている
1個のレコードが追加されるという、少々複雑な処理を行っている。

また、対義的に見るならば、INNER JOINとFULL JOINを対立関係に置いた方が解り易い。
その間にLEFT JOINとRIGHT JOINが来る。

本来、OUTER JOINと呼ぶべきものは、条件に合ったレコードと結合したものに、片方の分が空白のレコードと結合したものを加えたものであると思う。

CROSS JOINは結局の所、INNER JOINを無条件で行うものと等しく、INNER JOINの一種という扱いができる。
OUTER JOINと異なり、いずれか片方のテーブルが空の場合は、空の結果となる点に注意が要る。

対して、無条件のFULL JOINは、レコードが0~1の2つのテーブルを単にくっつけたい場合に使える。
CROSS JOINよりも使い道があるのではないかと思うが、CROSS JOINのような特殊な呼び方が見当たらないのが不可解。

2023.6.3


PostgreSQLで重複行削除

PostgreSQLで、全く同じ内容のレコードを作ってしまった場合に、これを片方だけ削除する方法に困っていた。
データベース管理システムによっては行ポインタというものが存在するそうで、利用できそうだが、PostgreSQLの場合はそれも見当たらない。
PostgreSQLの場合はoidというものがそれに相当しているらしいが、無いと言われる。

そんな中、ctidを利用する事で解決することがわかった。
ctidはユニークな隠しレコードみたいなもので、
SELECT ctid,* FROM (テーブル名);
の形で、各レコードデータとの対応表が得られる。
後はWHERE句で
ctid='(0,13)'
のように指定する事で、レコードを特定できる。

ctidは、update毎にカウントされるが、
vacuum full (テーブル名);
とする事で振り直される。

2022.3.24


プログラミング言語による剰余(余り)や累乗の表現

剰余累乗整数除算
(整数型同士)
非等値コメント
ExcelMOD(A; B)A ^ BROUNDDOWN(A / B)A <> B
CA % Bpow(A, B)A / BA != B//
BASICA mod BA ^ BA \ BA <> B'
JavaA % BMath.pow(A, B)A / BA != B//
JavaScriptMath.trunc(A / B)
PerlA % BA ** Bint(A / B)A != B#
RubyA / B
PythonA // B

2021.3.17