C++構造体のXmlシリアライザを自動生成したい
C#だったら属性を書くだけで済むけれど、C++はそういうわけにはいかないのでXMLで定義したフォーマットからコードを生成するスクリプトを書いた。
まずはデータフォーマットをXmlで表記する。
<?xml version='1.0' encoding='UTF-8'?> <Root> <Type name="Scene"> <Type name="Material"> <Type name="Property"> <value name="Name" type="String"/> <value name="Value" type="Float[]"/> </Type> <value name="Name" type="String"/> <value name="Properties" type="Property{}"/> </Type> <Type name="Mesh"> <Type name="Vertex"> <value name="Position" type="Float[]"/> </Type> <value name="Name" type="String"/> <value name="Vertices" type="Vertex[]"/> <value name="Indices" type="Integer[]"/> </Type> <Type name="Model"> <value name="Name" type="String"/> <value name="Material" type="String"/> <value name="Mesh" type="String"/> </Type> <value name="Name" type="String"/> <value name="Materials" type="Material{}"/> <value name="Meshes" type="Mesh{}"/> <value name="Models" type="Model{}"/> </Type> </Root>
struct Scene { struct Material { struct Property { std::string name; std::vector< float > value; }; std::string name; std::map< std::string, Property > properties; }; struct Mesh { struct Vertex { std::vector< float > position; }; std::string name; std::vector< Vertex > vertices; std::vector< int > indices; }; struct Model { std::string name; std::string material; std::string mesh; }; std::string name; std::map< std::string, Material > materials; std::map< std::string, Mesh > meshes; std::map< std::string, Model > models; }; void serialize(tinyxml2::XMLElement* out_xml, const Scene::Material::Property& in_value); void deserialize(Scene::Material::Property& out_value, const tinyxml2::XMLElement* in_xml); void serialize(tinyxml2::XMLElement* out_xml, const Scene::Material& in_value); void deserialize(Scene::Material& out_value, const tinyxml2::XMLElement* in_xml); void serialize(tinyxml2::XMLElement* out_xml, const Scene::Mesh::Vertex& in_value); void deserialize(Scene::Mesh::Vertex& out_value, const tinyxml2::XMLElement* in_xml); void serialize(tinyxml2::XMLElement* out_xml, const Scene::Mesh& in_value); void deserialize(Scene::Mesh& out_value, const tinyxml2::XMLElement* in_xml); void serialize(tinyxml2::XMLElement* out_xml, const Scene::Model& in_value); void deserialize(Scene::Model& out_value, const tinyxml2::XMLElement* in_xml); void serialize(tinyxml2::XMLElement* out_xml, const Scene& in_value); void deserialize(Scene& out_value, const tinyxml2::XMLElement* in_xml);
で、次のようなデータを読み込むことが可能になり
<?xml version='1.0' encoding='UTF-8'?> <Scene> <Name>PRIMITIVES</Name> <Materials> <Material> <Name>RED</Name> <Properties> <Property> <Name>Diffuse</Name> <value> <Float>1.0</Float> <Float>0.0</Float> <Float>0.0</Float> <Float>1.0</Float> </value> </Property> </Properties> </Material> </Materials> <Meshes> <Mesh> <Name>TRIANGLE</Name> <Vertices> <Vertex> <Position> <Float>0.0</Float> <Float>1.0</Float> <Float>0.0</Float> </Position> <Position> <Float>-0.866</Float> <Float>-0.5</Float> <Float>0.0</Float> </Position> <Position> <Float>0.866</Float> <Float>-0.5</Float> <Float>0.0</Float> </Position> </Vertex> </Vertices> <Indices> <Uint>0</Uint> <Uint>1</Uint> <Uint>2</Uint> </Indices> </Mesh> </Meshes> <Models> <Model> <Name>TRIANGLE_RED</Name> <Material>RED</Material> <Mesh>TRIANGLE</Mesh> </Model> </Models> </Scene>
次のように使う。
int main() { Scene scene; // 読み込み tinyxml2::XMLDocument doc; doc.LoadFile("deserialize_test.xml"); deserialize(scene, doc.FirstChildElement("Scene")); // 書き込み tinyxml2::XMLDocument doc2; auto* elem = doc2.NewElement("Scene"); doc2.InsertFirstChild(elem); serialize(elem, scene); doc2.SaveFile("serialize_test.xml"); return 0; }
おとなしくflatbuffersを使ってね
TransBook T90Chi T90CHI-32G を買ったあとやった事
コード書き専用マシンとして ¥30,000 で購入
不要なソフトウェアを削除
- Kingsoft office
- iフィルタ
- McAfee
- Asus Live Update
- Asus Web Storage
- Asus Screen Saver
- Asus Splendid Video Enhancement Technology
- Asus ATK Package
Windows10 にアップグレード
- https://www.microsoft.com/ja-jp/software-download/windows10
- cleanmgr → システムファイルのクリーンアップ → 以前のWindowsのインストール
Visual Studio Community 2015 をインストール
- Custom → C++ のみ選択
容量が32GBなので死にそう。SDカード買って仮想HD化する予定
ffmpeg flv to mp4
ffmpegを使ってflvをコンバートしたら動画がカクカクになってしまったのでメモ
環境
Windows 8.1 + ffmpeg static build
現象
- WMPではカクカクする
- GOM Playerで見ると普通の動画に見える
- Chromeではスローモーション再生
- 詳細情報を見るとフレームレートが1000になっている
- FLVのフレームレートは30とか普通の数字
テスト
ffmpeg -i test.flv test_raw.mp4 ffmpeg -i test.flv -vcodec mpeg4 test_codec.mp4 ffmpeg -i test.flv -r 60 -vcodec h264 test_60fps.mp4 ffmpeg -i test.flv -vsync passthrough test_vsync.mp4
結果
- 引数なしはカクカクな動画ができる (コーデックはh264)
- ビデオコーデックをmpeg4にするとカクカクしないけど汚い
- 明示的にビデオコーデックとフレームレートを指定すると解決した
- -vsync passthroughオプションでfpsがいい感じに設定されるっぽい
QPixmap from PIL Image
PILで作った画像を表示するときに便利
# conding: utf-8 import sys from PySide.QtCore import * from PySide.QtGui import * from PIL import Image, ImageQt # entry point if __name__ == '__main__': myapp = QApplication(sys.argv) # PILで画像読み込み img = Image.open('temp.png') # Qtで表示 pm = QPixmap.fromImage(ImageQt.ImageQt(img)) lbl = QLabel() lbl.setPixmap(pm) lbl.show() sys.exit(myapp.exec_())
PySide Dock配置とメニューからの表示切替
よく使うので自分用にメモ
# conding: utf-8 import sys from PySide.QtCore import * from PySide.QtGui import * # entry point if __name__ == '__main__': myapp = QApplication(sys.argv) wnd = QMainWindow() # Dock Widgets wnd.__c = QTextEdit(wnd) wnd.__l = QDockWidget("Left", wnd) wnd.__r = QDockWidget("Right", wnd) wnd.__t = QDockWidget("Top", wnd) wnd.__b = QDockWidget("Bottom", wnd) wnd.setCentralWidget(wnd.__c) wnd.addDockWidget(Qt.LeftDockWidgetArea, wnd.__l) wnd.addDockWidget(Qt.RightDockWidgetArea, wnd.__r) wnd.addDockWidget(Qt.TopDockWidgetArea, wnd.__t) wnd.addDockWidget(Qt.BottomDockWidgetArea, wnd.__b) wnd.setWindowTitle('gui example') wnd.statusBar() # Exit Action actionExit = QAction('&Exit', wnd) actionExit.setShortcut('Ctrl+Q') actionExit.setStatusTip('Quit application') actionExit.triggered.connect(wnd.close) m = wnd.menuBar().addMenu('&File') m.addAction(actionExit) t = wnd.addToolBar('Exit') t.addAction(actionExit) # Window Menu: toggle widget's visibility m = wnd.menuBar().addMenu('&Window') m.addAction(wnd.__l.toggleViewAction()) m.addAction(wnd.__r.toggleViewAction()) m.addAction(wnd.__t.toggleViewAction()) m.addAction(wnd.__b.toggleViewAction()) wnd.resize(640, 480) wnd.show() sys.exit(myapp.exec_())
DirectXでOBJファイル表示
こんな感じで簡単に読み込み処理が書ける。
#include "tiny_obj_loader.h" void CreateBuffer(ID3D11Buffer** io_buf, UINT in_byteWidth, UINT in_bindFlags, const void* in_data) { D3D11_BUFFER_DESC bd; ZeroMemory(&bd, sizeof(bd)); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = in_byteWidth; bd.BindFlags = in_bindFlags; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory(&InitData, sizeof(InitData)); InitData.pSysMem = in_data; g_pd3dDevice->CreateBuffer(&bd, &InitData, io_buf); } void Load(const char* in_path) { std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::material_t> materials; // OBJファイル読み込み std::string err = LoadObj(shapes, materials, in_path.c_str()); if (!err.empty()) return; CreateBuffer(&g_vb, mesh.positions.size() * sizeof(float), D3D11_BIND_VERTEX_BUFFER, &mesh.positions[0]); CreateBuffer(&g_ib, mesh.indices.size() * sizeof(unsigned int), D3D11_BIND_INDEX_BUFFER, &mesh.indices[0]); }
とりあえず自分で作ったテクスチャを貼れるようにしたい。
Node Graphでテクスチャ生成
Substance買うお金無い
Python
# conding: utf-8 import math from PIL import Image PI = 3.1415926536 # 正弦 class Sin: def __init__(self, in_x): self.x = in_x def __call__(self): return math.sin(self.x()) # 余弦 class Cos: def __init__(self, in_x): self.x = in_x def __call__(self): return math.cos(self.x()) # 最大 class Max: def __init__(self, in_x, in_y): self.x = in_x self.y = in_y def __call__(self): x = self.x() y = self.y() return x if x >= y else y # 束縛 class Const: def __init__(self, in_value): self.value = in_value def __call__(self): return self.value # 加算 class Add: def __init__(self, in_x, in_y): self.x = in_x self.y = in_y def __call__(self): return self.x() + self.y() # 減算 class Sub: def __init__(self, in_x, in_y): self.x = in_x self.y = in_y def __call__(self): return self.x() - self.y() # 乗算 class Mul: def __init__(self, in_x, in_y): self.x = in_x self.y = in_y def __call__(self): return self.x() * self.y() img = Image.new("L", (256, 256)) p = img.load() for y in range(256): for x in range(256): u = Const(x / 256.0) v = Const(1.0 - (y / 256.0)) r = Const(2.0 * PI * -0.02) s = Sub(Mul(u, Cos(r)), Mul(v, Sin(r))) t = Add(Mul(v, Cos(r)), Mul(u, Sin(r))) freq = Const(2.0 * PI * 10.0) lhs = Cos(Mul(s, freq)) rhs = Cos(Mul(t, freq)) F = Max(lhs, rhs) p[ x, y ] = int(F() * 255) img.show()