Hello World / plɹoM ollǝH

Programmers Live in Vain

DirectX11 Efficient Buffer Management

未だに参照するけどスライド探すのに時間かかってしまうのでメモ http://gamedevs.org/uploads/efficient-buffer-management.pdf

これは知っとけ的な

  • API呼び出しは可能な限り減らす
  • 16バイトアライメントする(最大30倍速度差が出る)
  • D3D11Deviceはmutexを使うが、各DeviceContextは一度に1スレッドからしか呼び出せない
  • UpdateSubresourceはCPU時間を食う。できればMap/Unmapを使う
  • CPU-GPU間のSyncPointをなるべく減らす

各バッファの使い分け

TypeUsage (e.g)Create FlagUpdate Method
ForeverLevel BSPsIMMUTABLECannot Update
Long-LivedCharactersDEFAULTUpdateSubResource
TransientUI/TextDYNAMICCTransientBuffer
TemporaryParticlesDYNAMICMap/NO_OVERWRITE
ConstantMaterial PropsDYNAMICMap/DISCARD

Efficient Buffer Managementっつうタイトルが出てこないんですわ

Qt ビルドする(GPL版)

リリースDLLのPDBが欲しかったのでビルドする
ここを見れば大体わかる
https://doc.qt.io/qt-5.6/windows-building.html

わしの環境

  • Windows10やで
  • Visual Studio 2015をインストールしているものとする
  • とりあえず Qt5.10.1

Qtダウンロード

  1. QtのホームページからOpen Source版のインストーラをダウンロードして実行
  2. NextとかSkipを適当に押して進めていくとリポジトリのフェッチが始まる
  3. インストール先選択後はインストールするコンポーネントを選択する
    自分のビルドしたいバージョンのSources以外のチェックは全部はずした
  4. ライセンス条項に同意するとダウンロード&インストールが始まる
    めっちゃ時間かかるで

ビルド

  1. 例によってvcのパスを通しておく

    "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64

  2. ソースコードのルートディレクトリに移動してconfigureを実行する
    ここでもライセンスの同意をもとめられたりする

    configure -release -force-debug-info -nomake examples -opensource

    ちなみに help オプションを付ければ指定できるオプション一覧が表示される

    configure -help

    DirectX関係で怒られた場合はWindowsSDKのパスも通す

    set PATH=%PATH%;C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x64

  3. nmakeを実行する(そして永久に終わらないビルドが始まる)

    nmake

Src\qtbase\lib以下にdllやらpdbやらができるので、これを使ってPySideのwheelを作成しておけば、Qt内部でエラーが起こったときもシンボルを読み込んである程度追うことができる。良かった良かった。

PySide2 終了時のメモリアクセスエラー

f:id:dungeonneko:20180305180811p:plain

原因調べるのが面倒くさいので困ります

from PySide2 import QtWidgets
import sys

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = QtWidgets.QMainWindow()

    action = QtWidgets.QAction(main)
    action.setText('Action')
    action.triggered.connect(lambda: print('action executed'))
    menu = QtWidgets.QMenu('menu')
    menu.addAction(action)
    main.menuBar().addMenu(menu)
    main.show()
    sys.exit(app.exec_())

↑たとえばコレ。一見ちゃんと動いてそうなプログラムですが、メニューからアクションを実行すると終了時にエラーが出ます。こんなのPySide1でも起きてましたっけ?これを回避するには

# parentをちゃんと指定する
# QMenuを入れ子にする場合も全部のSubmenuに指定する
menu = QtWidgets.QMenu('menu', main) 

こう書いておく必要があります。デフォルト引数で「parent = Q_NULLPTR」とか書いてあるからaddMenuしたときに設定してくれるのかな~とか、淡い期待を抱いてた時期が私にもありました(なんでデフォルトNULLなんだい?)とりあえずメモリアクセスエラーに出会ったらparent指定してない箇所を見なおすことにしました。QtビルドしてPDB作るのは面倒くさいからやらないです⇒やりました

CryptoJSで画像を暗号化してみたり

https://code.google.com/archive/p/crypto-js/

ただやってみただけ

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ANGOUKA</title>
</head>
<body>
    <input id="selfile" type="file" /><br />
    <image id="preview"></image><br />
    <input id="password" type="text" value="password" /><br />
    <input id="encrypt" type="button" value="encrypt" /><br />
    <textarea id="encdata"></textarea><br />
    <input id="decrypt" type="button" value="decrypt" /><br />
    <image id="restore"></image><br />
    <script src="js/crypto-js/rollups/aes.js"></script>
    <script src="js/crypto-js/rollups/sha256.js"></script>
    <script>
        window.onload = function () {
            var selfile = document.getElementById("selfile");
            var encrypt = document.getElementById("encrypt");
            var preview = document.getElementById("preview");
            var password = document.getElementById("password");
            var encdata = document.getElementById("encdata");
            var decrypt = document.getElementById("decrypt");
            var restore = document.getElementById("restore");

            selfile.addEventListener("change", function () {
                var url = selfile.files[0];
                if (!url) return;
                var fr = new FileReader();
                fr.onload = function () { preview.src = fr.result; }
                fr.readAsDataURL(url);
            });

            encrypt.addEventListener("click", function () {
                var h = CryptoJS.SHA256(password.value).toString(CryptoJS.enc.Base64);
                encdata.value = CryptoJS.AES.encrypt(preview.src, h).toString();
            });

            decrypt.addEventListener("click", function () {
                var h = CryptoJS.SHA256(password.value).toString(CryptoJS.enc.Base64);
                restore.src = CryptoJS.AES.decrypt(encdata.value, h).toString(CryptoJS.enc.Utf8);
            });
        };
    </script>
</body>
</html>

Chromeのコンソール画面で遊ぶ(SVG編)


Check console log in Google Chrome!
えぇっ!?IEを使っているだって?君は正気か?

three.js Chromeローカルファイル読み込みで怒られたよ

three.jsのサンプルローカルで実行してたら怒られたのでメモ

Failed to load **** Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

ローカルサーバー建てるのは面倒くさいので
起動オプション付きのショートカットを用意する

「ショートカット」タブの「リンク先」に下記オプションを追加して

--allow-file-access-from-files

「ショートカット」タブの「詳細設定」⇒「管理者として実行」にチェックを
「互換性」タブにも「管理者としてこのプログラムを実行する」が存在するが
こちらをチェックするとexe自体の起動設定が管理者権限になってしまうので注意

Chromeのプロセスを全部終了してから↑のショートカットで起動させる
これでエラー回避できるんやで

pythonのreversedはイテレータを返す

反転したリストを複数回使うときにハマった

a = reversed([1, 2, 3])  # イテレータを返す
for x in a:
    print(x)
for x in a:
    print(x)  # ここは呼ばれない

reverseなどでリスト自体を反転させておくか

a = [1, 2, 3]
a.reverse()

for文ごとにreversedを呼べばOK

a = [1, 2, 3]
for x in reversed(a):
    print(x)
for x in reversed(a):
    print(x)

ちなみにsortedはリストを返す模様