ドキュメントも何もないし一人で使う予定なので公開と言えるのか分からないが、ゲーム制作に使う用のライブラリを公開した。
sinenの名前の由来は「思念」から。あとアイヌ語で「一人」の意味もあるらしいので丁度良かった。 DXライブラリよりも少し抽象度の低いあたりを目指している。主にSDL2を中心としており、描画部分はOpenGLかVulkanが担う.
sudo mkdir -p /opt/factorio sudo chown 845:845 /opt/factorio sudo docker run -d \ -p 34197:34197/udp \ -p 27015:27015/tcp \ -v /opt/factorio:/factorio \ --name factorio \ --restart=always \ factoriotools/factorio
Factorioサーバーを建てるためには、公式サイトからHeadless Serverをダウンロードして起動する必要がある。
Factorioサーバー起動時にはglibc2.18が必要となるが、CentOS7では標準でglib2.17が使用されている。
glibcとはGNUのC言語実装ライブラリであるが、安易にglibcを導入するとカーネルが起動しなくなる恐れがある(なった)。
そのため、次の手段としてdockerを使用することにした。
以下で紹介するのはCentOS7での方法である。
Dockerを入れる前に、ポートの開放とファイアウォールを通す必要がある。Factorioで使用するポートは34197(UDP)だ。
# firewall-cmd --add-port=34197/udp --zone=public --permanent
# yum -y install docker
# systemctl start docker
今回は一番メンテナンスがされているfactoriotoolsのコンテナを使用する。
https://hub.docker.com/r/factoriotools/factorio/
公式のガイドに沿って進めれば基本的に問題ない。
sudo mkdir -p /opt/factorio sudo chown 845:845 /opt/factorio sudo docker run -d \ -p 34197:34197/udp \ -p 27015:27015/tcp \ -v /opt/factorio:/factorio \ --name factorio \ --restart=always \ factoriotools/factorio
ただし、気をつけるべき点は上記のままでは最新版になってしまう。安定版では無いということで、すなわち公式サイトのExperimentsを含む最新のバージョンのことである。
例えば執筆時点のFactorioの最新バージョンは1.1.21だが、Experiments版は1.1.25だ。もし1.1.21のサーバーを建てるには、
sudo mkdir -p /opt/factorio sudo chown 845:845 /opt/factorio sudo docker run -d \ -p 34197:34197/udp \ -p 27015:27015/tcp \ -v /opt/factorio:/factorio \ --name factorio \ --restart=always \ factoriotools/factorio:1.1.25
のように末尾に「:」とバージョンを書けば良い。
ドキュメントの通り、
# docker start factorio
# docker stop factorio
# docker logs factorio
私の環境だけの問題かもしれないが、初回実行時にPermission deniedが出た。ディレクトリの権限を変えたりなど色々試したが駄目だったので、一時的にセキュリティを外した。
一時的に外すためには、
# setenforce 0
とする。
ただしこれは最後の手段であるのでおすすめしない。
サーバーを建て終わったら、
# setenforce 1
でSELinuxを再度有効化しておく。
新年です。だからなにって訳ではないですが。
最近、コマンドラインからビルドしたいなーと思っていて調べたところMSBuildというのが使えるらしい。 はてなブログタグに登録されているくらい。 場所は
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\
にある。(2019は任意のバージョン) 面倒なのでとりあえず環境変数に打ち込んだ。
MSBuild.exeをターミナルから実行できるのを確認したら、↓こんな感じにビルドすることができる。
MSBuild C:/hoge/fuga/piyo.sln /t:build /p:Configuration=Debug;Platform="x86"
ソリューションに複数のプロジェクトがある場合は/t:にbuild、任意のプロジェクトをビルドしたいときにはプロジェクト名に変更することでビルド可能。
その他ConfigurationとPlatformは見ての通りで、これでおそらく最低限はビルド可能になる。
それ以外のコマンドは公式ドキュメントを読んでください。結局デバッガなどを使用するとなるとVisual Studioを起動する羽目にはなると思います。
docs.microsoft.com
毎回打つのは面倒なのでaliasに登録してるんですが、makefileみたいになんかもっとスマートに出来ると思うのでよければ教えて下さい。
追記:調べたところ、nmakeというのがやっぱりあるらしい。書き方もmakefileに似ているので、今後書く予定。
この記事は落書きです.
Vulkanに関する日本語の情報が少ないので、落書きでももしかしたら需要あるかもしれんので公開することに.
とはいえ、仕様書を読んだわけではないので信頼性は低い。
ウインドウの生成やらをしておく. 私はSDL2.0を使った.
vkCreateInstance()でインスタンスの生成が可能.
検証レイヤの有効化もこの時点で行う.
生成に成功したかどうかはVk_Resultを使うのが良い.成功時のVK_SUCCESSは0を返すので, ポインタの感覚で判定すると痛い目に合う.
GPUを列挙して選ぶ.
vkEnumeratePhysicalDevices()で列挙できる.
特に理由が無ければ一番最初のデバイスを選んどけば問題ないと思う.
CPUとGPU間のキュー.
vkGetPhysicalDeviceQueueFamilyProperties()で列挙.
開放する順番が決まっているので面倒くさい. もしレンダラを一つしか生成しないのであればOSに任せてしまってもいいかもしれない.
やることがめちゃ多い. 取り合えず枠だけ書いた.気が向いたら更新予定.
いちいちVisual Studio を毎回起動するのがめんどくさくなってきた。だらだらアニメでも見ながらプログラムを組みたいときだってある。
MSBuild使えばコマンドラインからビルドできるので、VSCodeのターミナルから起動すれば色々便利!
"settings": { "terminal.integrated.shell.windows": "C:\\Windows\\Sysnative\\cmd.exe", "terminal.integrated.shellArgs.windows": [ "/k", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\Tools\\VsDevCmd.bat" ] }
パスが異なる場合適宜書き換えてください。これをsettings.jsonなり.code-workspaceに貼り付けてください。
"&&"で起動後のコマンドを書くこともできます。なので例えば
"terminal.integrated.shellArgs.windows": [ "/k", "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\Tools\\VsDevCmd.bat", "&&", "doskey", "/macrofile=macros.txt" ]
と書いてmacros.txtにマクロを書くことができます。マクロについてはMicrosoftのドキュメントを参照してください。
C++向けGUIライブラリ Qt には毎回実行されるような関数は用意されていない。
しかし、Qtにはシグナルとスロットという仕組みが存在し、それを使って自前で簡単に実装することが可能であることを知ったので記しておく。
シグナル及びスロットを詳しく知りたい場合は、Qtの公式リファレンスか、Qiitaなどにいくつかサイトを見つけたのでそちらを参照すると良い。 doc.qt.io 簡単に言えば、シグナルはスロットを作動させるための信号で、スロットは関数である。
今回のupdate関数は、一定時間ごとに呼び出すのでQTimerクラスを使って時間を計測し、シグナルを送信させる。
まずは適当なクラスにQTimerクラスのポインタを作る。
//QtWidgetApplication1.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication1.h" class QtWidgetsApplication1 : public QMainWindow { Q_OBJECT public: QtWidgetsApplication1(QWidget *parent = Q_NULLPTR); ~QtWidgetsApplication1(); private: Ui::QtWidgetsApplication1Class ui; class QTimer* my_timer; };
今回は、プロジェクトを作成したときの最初のクラスに作る。
次にスロットのプロトタイプを作成する。
//QtWidgetApplication1.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_QtWidgetsApplication1.h" class QtWidgetsApplication1 : public QMainWindow { Q_OBJECT public: QtWidgetsApplication1(QWidget *parent = Q_NULLPTR); ~QtWidgetsApplication1(); public slots: void update(); private: Ui::QtWidgetsApplication1Class ui; class QTimer* my_timer; };
真ん中のvoid update();がスロットである。public にslotsを加えなければならない事に注意が必要である。
update関数には一定周期で実行したい処理を実装しておく。試しに今回は、QLineEditウィジェットを作成し、経過時間を表示させる。
次に、中身を書く。
コンストラクタには、my_timerの実体を生成と、シグナルとスロットの接続 ( connect ) を行っている。
connectの引数は第一引数から順番に(シグナル送信元、シグナル、シグナル送信先(受信者)、スロット)である。
今回の場合、my_timerがシグナルが送信元となり、timeout()が呼ばれるタイミングで送信される。timeout()は、QTimerが0になった時に呼ばれる。
シグナルの受信者はQtWidgetApplication1クラス、スロットはupdate()である。
つまり、これでmy_timerが0になるたびにupdate()が呼ばれるようになった。
次にmy_timerをスタートさせる。引数にはタイマーの時間 (ms) をセットする。my_timerはtimeout()が呼ばれるたびに100になり、以後自動的にスタートする。
//QtWidgetApplication1.cpp #include "QtWidgetsApplication1.h" #include <QtGui> #include <iostream> QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); my_timer = new QTimer(); connect(my_timer, SIGNAL(timeout()), this, SLOT(update())); my_timer->start(100); } QtWidgetsApplication1::~QtWidgetsApplication1() { delete my_timer; } void QtWidgetsApplication1::update() { static uint32_t time = 0; time += 100; ui.lineEdit->setText(std::to_string(time).c_str()); }
実行させると以下のように値が増加し、update関数が完成した。
Amazonレビューにでも書けば良かった気もしますが、ブログの方が気楽なのでここにレビューを書きます。
アフィだと思われないようにAmazonのリンクは控えますが、5000円程度です。
私がC++をちまちま書き始めてからだいぶ経ち、それなりにライブラリに頼ってゲームを作ることも出来るようになったのでさらなる高み(?)へ行くために手を取ってみました。あと単純にエンジンとかライブラリに頼らずに作りてえなという意地もありまして、この本の中でOpenGLを扱っているという情報を入手しました。
買ったのは今年の4月の頭だったので、丁度2月にDirectX12の書籍も出ていたので迷ってはいたものの、流石に基礎もまともに身についてないのにわざわざクッソ低レイヤなDirectX12に手を出す訳にもいかず。それに本の厚さは同じくらいですが、DX12の本はレンダリングに関することしか載ってないのに対してゲームプログラミングC++はオーディオとか入力処理といったゲーム全般について書かれているのでC++一本でゲーム作るならこっちだなという結論を自分の中で出しました。
読者の対象者として想定されているのが「そこそこC++が書ける人かつゲーム制作自体はあまりやっていない人」のようなので、難易度は丁度良かった(ただ個人的に数学や物理は難しい)です。しかし、所々コードが端折られている箇所がありました。書籍のソースコードは章ごとにGitHubのリポジトリに入れられているのでそっちを見ればいいのですが、手を動かしながら読むように設計されているので買う時は注意してください。
全部で14の章の別れており、それぞれ内容が独立しています。各章と概要を書きます(問題があれば消します)。
おまけ:中級C++の復習(参照、ポインタ、配列、クラス、演算子オーバーロード、STLコンテナ各種、range-based-for文など)
見ての通り、開発に必要な最低限の知識が盛り込まれています。また独立していると書きましたが、全てが完全に独立している訳ではなく、例えば4,5,8章は3章の知識を前提として書かれています。
できればマルチスレッドも取り入れてほしかった…
著者が言うには「おとなしくゲームエンジン・アーキテクチャ読め」ということらしい。あんな鈍器買えるかーっ!
追記:ゲームエンジン・アーキテクチャ第3版が出るそう(ソースはTwitter)なので多分買います。
何か本の推薦文みたいでレビューとは違うような気がする。が、しかし疲れたのです。これが惰性クオリティであります。
とはいえこの本は個人的に名著でした。5000円とか高すぎだろと思っていましたが、読者層が被っていれば値段以上の情報を得られます。ネットで探し集めたくらいじゃ得られないことが載っていました。まあそのために5000円近く払うんですが。