5月25日は auto の話。(4日目 #毎日3分 C++11。)

毎日少しずつ C++11 を楽しんでいきましょう。ちょっとした息抜きの間に読める本当に短いお話、最悪の4日目。1年ぶりくらいに体調を崩してしまいました。風邪薬を飲んで朦朧としているので今日はほんとに短いお話。

5月25日の C++11 は auto です。使い方はこちら:

1
auto scaleFactor = 1.0f;

この scaleFactor は変数です。上のコードは変数の定義と初期化をあらわしています。さて、scaleFactor の型はなんでしょうか?
auto 型? …いえ、実は float 型です。

auto型推論を行うキーワードとして C++11 から追加されました。もともとautoは C/C++ に予約語としてありました。その時の意味合いは、自動変数を明示的に示す「記憶クラス指定子」でしたが、めったに使う場面がありませんでした。C++11 では「型推論」を行うキーワードとして頻繁に使うことになります。

1
2
3
4
5
6
7
8
9
10
11
auto scaleFactor = 1.0f; // float
auto ten = 10U; // unsigned int
auto text = std::string(); // std::string
auto const scaleFactor2 = 1.0f; // float const
auto ptr = &scaleFactor; // float*
auto ptr2 = &scaleFactor2; // float const*
auto const ptr3 = &scaleFactor; // float* const
auto & scaleFactor3 = scaleFactor2; // float const&
auto unknown; // error

(なんとなく見えてきたかな?)

型推論

次のコードは tomoyo という変数を定義し、初期化するコードです:

1
2
3
4
5
6
7
8
9
std::map<
std::string,
std::shared_ptr<std::vector<int> >
> const namedBuffers;
std::map<
std::string,
std::shared_ptr<std::vector<int> >
>::const_iterator const tomoyo = std::end(namedBuffers);

長いですね。std::end(namedBuffers) の返却値の型は、std::map<std::string, std::shared_ptr<std::vector<int> > >::const_iterator です。

そうであれば、tomoyo の型も同じ std::map<std::string, std::shared_ptr<std::vector<int> > >::const_iterator になるはずです。

これまでは変数を定義するときにわざわざ、std::map<std::string, std::shared_ptr<std::vector<int> > >::const_iterator tomoyo = なんて明示的に書く必要がありました。(明らかに tomoyo の型はわかっているのに!!)

変数の初期化子によって型が一意に決まるのですから、その場合に限り、明示的に型を書かなくてもいいはずです。そこで登場するのが auto です。

1
auto const tomoyo = std::end(namedBuffers);

短いです。これが型推論です。推論するから「型推論」。何度でも言いましょう、これが型推論です。

補足

ちなみに、初期化子がないときは型推論できませんのでエラーになります:

1
auto const tomoyo; // error

冒頭で書きました通り、元々記憶クラス指定子として auto が使われてきた歴史がありますが、こんな書き方も C++11 ではおっけーになります:

1
2
static auto a = 1.0f; // static float
register auto b = 1.0f; // float

auto 便利でしょう?

iterator のほかに、lambda や std::bind, std::function を使うときなどなど、いろんな場面でこの auto を本当によく使います。(lambda についてはまた機会を見つけてお話できたらいいですね。)

ちなみに型推論がサポートされている言語として Haskell が有名です。型推論の面白さに触れたい方は Haskell について調べてみるといいかもしれません。
今日はここまで。少しでも Haskell に興味を持っていただけたら幸いです。


Haskell を始めるならこちらから:
http://www.haskell.org/haskellwiki/Haskell

テーマ上、さくっと読んですぐ使える部分に的をしぼって書いています。置いてけぼりにしている仕様や詳しい話を知りたい場合は、次もぜひ参照してみてください:

http://isocpp.org/
http://www.boost.org/

誤字脱字、またはよろしくない部分などありましたら、コメントにてお願いします。

(追記:2013/05/26)
起きて改めて読んでみたら誤字脱字が多かったので補足の追加も含め、追加編集しました。

5月24日は std::array の話。(3日目 #毎日3分 C++11。)

毎日少しずつ C++11 を楽しんでいきましょう。ちょっとした息抜きの間に読める本当に短いお話、驚きの3日目。もしかしたら今日で最後かもしれません。

5月24日の C++11 は std::array です。使い方はこちら:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <array>
std::array<float, 3> position = {10.0f, 20.0f, 30.0f};
std::array<float, 16> matrix = {
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
};
matrix[12] = position[0];
matrix[13] = position[1];
matrix[14] = position[2];

ピュアな固定長配列と std::array

std::array は誤解を恐れずに言えば、「ただの固定長配列」です。

1
2
3
4
5
// 今までの固定長配列
int fixedArray[4];
// std::array を使った固定長配列
std::array<int, 4> fixedArray;

なので、今までソースコード中に使っていた固定長配列の箇所を std::array に変えていただいても問題なく動きます。

気になるのは std::array よりも、今まで使っていた「ピュアな固定長配列」を使ったほうがオーバーヘッドでないんじゃないの?ということです。結論からいうと、最近のコンパイラで最適化をオンにすれば、ピュアな配列とほとんど同じコードになります。その理由は、std::array の実装を見てみるとわかります。

1
2
3
4
5
6
7
8
9
template <typename T, size_t N>
struct array
{
T elem[N];
// operators ...
// iterator ...
// data()/data() const
};

実はクラステンプレート中のメンバに、ピュアな固定長配列を使っています。最適化をオンにしてインライン展開されたら今までの固定長配列とほとんど同じになりそうですよね。(コンパイラによって動きが違うので一概には言えませんが、人間が気にするほどのオーバーヘッドにはならないでしょう。)

std::array と強力な algorithm

では std::array を使うメリットはなんでしょうか。それは他の STL に含まれるコンテナ(std::vector, std::map)と同じように <iterator><algorithm> が使える点にあるでしょう。
今までは、配列の初期化をこんなふうにしていました:

1
2
3
int a[10];
for (size_t i = 0; i < 10; ++i)
a[i] = 0;

std::array だと <algorithm>std::fill が使えます:

1
2
3
4
5
#include <array>
#include <algorithm>
std::array<int, 10> a;
std::fill(std::begin(a), std::end(a), 0);

「それくらい for 文でいいんじゃない?」と言う声が聞こえてきますね。ですがここで std::fill を使う理由は2つあります。1 つは 配列の長さが変わったときです。for 文を使った場合、条件式である “i < 10” のところを変更する必要があります。

1
2
3
4
int a[12340000];
for (size_t i = 0; i &lt; 10; ++i) // bug
a[i] = 0;

std::array であれば長さが変わろうが、コンテナが std::list になろうが、&lt;algorithm&gt; には影響しません。

1
2
3
std::array&lt;int, 12340000&gt; a;
std::fill(std::begin(a), std::end(a), 0);

もう1つ、std::fill のような &lt;algorithm&gt; を積極的に使うことで、初めて読んだ人でも「何をするコードなのか」をすぐに理解できるメリットがあります。次のコードは何をしているコードかわかりますか?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int* iter = nullptr;
int a[6] = { 0, 1, 2, 3, 4, 5 };
for (size_t i = 0; i &lt; 6; ++i)
{
if (a[i] == 3) {
iter = &amp;(a[i]);
break;
}
}
if (iter == nullptr)
std::cout &lt;&lt; &quot;'3': cannot find.&quot;
else
std::cout &lt;&lt; &quot;'3': already exists.&quot;

上のコードはぱっと見わかりにくいですね。
代わりに &lt;algorithm&gt;std::find を使ってみましょう:

1
2
3
4
5
6
7
8
std::array&lt;int, 6&gt; a = { 0, 1, 2, 3, 4, 5 };
auto const iter = std::find(std::begin(a), std::end(a), 3);
if (iter == std::end(a))
std::cout &lt;&lt; &quot;'3': cannot find.&quot;
else
std::cout &lt;&lt; &quot;'3': already exists.&quot;

std::find が行うことはただ1つだけですから、誰が解釈しても同じ解釈にたどり着きます。
for 文を使って、冗長で、ユニークな、独自のアルゴリズムを書くのは、考えるのも大変ですし、腕も疲れます。読んでいる人にとって理解するのも大変です。唯一ジャン・フランソワ・シャンポリオン氏、彼なら解読できるかもしれません。

std::array で固定長バッファ

C から受け継がれた(邪悪な)低レベルな部分を C++ は受け継いでいます。その最も象徴的なコードが、配列と生ポインタ、そして std::memcpy と言っても過言ではありません。

1
2
3
4
5
6
7
8
9
void WickedCopy(float const* source, size_t length)
{
float dest[128];
for (size_t i = 0; i &lt; 128; ++i)
dest[i] = 0.0f;
assert(128 &gt;= length);
std::memcpy(&amp;(dest[0]), source, length);
}

もちろん、std::array でも同様の処理を書くことができます。ピュアな固定長配列の先頭ポインタを取得する data 関数が用意されています。

1
2
3
4
5
6
7
8
void WickedCopy(std::vector&lt;float&gt; const&amp; source)
{
std::array&lt;float, 128&gt; dest;
std::fill(std::begin(dest), std::end(dest), 0.0f);
assert(dest.size() &gt;= source.size());
std::memcpy(dest.data(), source.data(), source.size());
}

可変長配列の std::vector も同じように C++11 では data 関数が追加されました。こういった「メモリ」を直接触るような個所でも std::array は十分便利に使えます。

なんといっても

固定長配列を他のクラスや構造体、あるいは STL コンテナと同じように std::array 型として扱えるのは嬉しいですね。

C++11 ではより「型」を意識する場面が多くなりました。他にも面白いものから便利なものまでいろいろ C++11 はありますが、今日はここまで。少しでも C++11 に興味を持っていただけたら嬉しい限りです。


std::array についてはこちら:
http://en.cppreference.com/w/cpp/container/array

boost::array もご一緒に:
http://www.boost.org/libs/array

テーマ上、さくっと読んですぐ使える部分に的をしぼって書いています。置いてけぼりにしている仕様や詳しい話を知りたい場合は、次もぜひ参照してみてください:

http://isocpp.org/
http://www.boost.org/

誤字脱字、またはよろしくない部分などありましたら、コメントにてお願いします。

5月23日は static_assert の話。(2日目 #毎日3分 C++11。)

毎日少しずつ C++11 を楽しんでいきましょう。ちょっとした息抜きの間に読める本当に短いお話、奇跡の2日目。これが最後だと思います。こんなに続くとは思いませんでした。

5月23日の C++11 は static_assert です。使い方はこちら:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include &lt;type_traits&gt;
template &lt;typename T&gt;
struct Radian
{
static_assert(std::is_floating_point&lt;T&gt;::value,
&quot;T is an floating-point type.&quot;);
float value;
};
Radian&lt;float&gt; rad1; // ok
Radian&lt;double&gt; rad2; // ok
Radian&lt;long double&gt; rad3; // ok
Radian&lt;int&gt; rad4; // error
Radian&lt;char*&gt; rad5; // error
Radian&lt;std::string&gt; rad6; // error

実行時アサートと静的アサート

static_assert はその名の通り、静的なアサート(assert)です。これまでの assert は実行時に呼び出していました。

1
2
3
4
5
int Divide(int a, int b)
{
assert(b != 0);
return a / b;
}

前提として満たされるべき条件を assert として書きます。そして、デバッグ時に万が一、条件が満たされていないなんて場合にエラーを出力します。
ただしメタプログラミングにおいては、実行時アサートはあまり役に立ちません。

1
2
3
4
5
6
7
8
template &lt;typename T, size_t N&gt;
struct Array
{
// こんな書き方したくてもできません:
assert(0 &lt; N); // error
T data[N];
};

そこで C++11 で追加されたのがメタプログラミングで使える静的なアサートこと static_assert です。

1
2
3
4
5
6
7
8
9
10
template &lt;typename T, size_t N&gt;
struct Array
{
static_assert(0 &lt; N, &quot;1 or more than 1&quot;); // ok
T data[N];
};
Array&lt;int, 4&gt; a; // ok
Array&lt;int, 0&gt; b; // error

static_assert の条件式が満たされない場合、コンパイルエラーとして出力されます。この static_assert、テンプレートメタプログラミングを行う場合に非常に大活躍します。

型特性(type traits)と組み合わせて超絶ハッピー

C++11 から標準ライブラリに &lt;type_traits&gt; が追加されました。&lt;type_traits&gt; は型特性(type traits)を扱うのに便利なライブラリで、boost 由来のライブラリです。

&lt;type_traits&gt; についての詳しい話はまた今度。ですが、static_assert と組み合わせると、ちょっとしたところでも使える大変便利なものになるので少しだけ紹介しましょう。
&lt;type_traits&gt; に含まれる std::is_integral というのがあります:

1
2
3
std::cout &lt;&lt; std::is_integral&lt;int&gt;::value; // true
std::cout &lt;&lt; std::is_integral&lt;float&gt;::value; // false
std::cout &lt;&lt; std::is_integral&lt;char*&gt;::value; // false

この std::is_integral は与えられた型が整数(integral)かどうかを判断することができます。もちろん、これはメタ関数なのでランタイム時ではなくコンパイル時に評価されます。

一番最初に挙げた例を見てみましょう。この例では &lt;type_traits&gt;std::is_floating_point を使っています。

1
2
3
4
5
6
7
8
9
#include &lt;type_traits&gt;
template &lt;typename T&gt;
struct Radian
{
static_assert(std::is_floating_point&lt;T&gt;::value,
&quot;T is an floating-point type.&quot;);
float value;
};

Radian&lt;T&gt; 型を作ってみたものの、このクラステンプレートを使うユーザは T に何をいれるかわかりません。
もしかしたら

1
2
3
4
5
Radian&lt;
std::map&lt;std::string, std::vector&lt;
std::shared_ptr&lt;std::tuple&lt;std::uint32_t, std::int32_t&gt; &gt;
&gt; &gt;
&gt; fus_ro_dah;

なんて型を定義するかもしれません。

そんなときに static_assert&lt;type_traits&gt; を使います。

1
2
static_assert(std::is_floating_point&lt;T&gt;::value,
&quot;T is an floating-point type.&quot;);

これにより、浮動小数点型のみ有効になります。

1
2
3
4
5
6
7
Radian&lt;float&gt; rad1; // ok
Radian&lt;double&gt; rad2; // ok
Radian&lt;long double&gt; rad3; // ok
Radian&lt;int&gt; rad4; // error
Radian&lt;char*&gt; rad5; // error
Radian&lt;std::string&gt; rad6; // error

使う側もコンパイルエラーだったらすぐに過ちに気づけます。static_assert は本当にいろんな場面で使えます。
例えば DirectXTK の実装を見てみると、必要なところに適宜 static_assert を使っていたりします。

C++11 はこれまでよりも静的で、より型を意識したコードを書くために工夫されています。static_assert&lt;type_traits&gt; はその中の 1 つです。

まだまだもっともーーーーーっと面白いものがたくさんあります。でも今日はここまで。少しでも興味を持っていただけたら嬉しい限りです。


std::is_floating_point についてはこちら:
http://en.cppreference.com/w/cpp/types/is_floating_point

テーマ上、さくっと読んですぐ使える部分に的をしぼって書いています。置いてけぼりにしている仕様や詳しい話を知りたい場合は、次もぜひ参照してみてください:

http://isocpp.org/
http://www.boost.org/

誤字脱字、またはよろしくない部分などありましたら、コメントにてお願いします。

5月22日は enum class の話。(1日目 #毎日3分 C++11。)

今日から少しずつ C++11 を楽しんでいきましょう。ちょっとした息抜きの間に読める本当に短いお話を書いていきます。
毎日続けて記事を投稿できるよう、雑に短くお話を書いていきます。三日坊主なので第3回の連載まで続けられたらごはんをおごってほしいです。

5月22日の C++11 は “enum class” です。使い方はこちら:

1
2
3
4
5
6
7
8
9
enum class PrimitiveType: std::size_t
{
TriangleList = 0,
TriangleStrip,
LineList,
LineStrip,
};
PrimitiveType primitiveType = PrimitiveType::TriangleStrip;

これまでの enum と enum class

この enum class を使う利点は 2つあります。
まず今までの enum こと列挙型は C の機能を引き継いだため、(PrimitiveType のような)型名による名前空間がありませんでした。”TriangleList” のような列挙定数がグローバルな名前空間に存在することになります。

1
2
PrimitiveType primitiveType1 = TriangleList; // ok
PrimitiveType primitiveType2 = PrimitiveType::TriangleList; // error or warning C4482

そのため今でも列挙定数にプリフィックスの「k」をつけているソフトウェアは少なくありません。

1
2
3
4
5
6
7
enum PrimitiveType
{
kTriangleList = 0,
kTriangleStrip,
kLineList,
kLineStrip,
};

こうした問題にたいして C++03 時代では、苦し紛れな解決策として struct 名前空間にいれる方法もありました。

1
2
3
4
5
6
7
8
9
10
11
12
struct PrimitiveType
{
enum Type
{
TriangleList = 0,
TriangleStrip,
LineList,
LineStrip,
};
};
PrimitiveType::Type primitiveType = PrimitiveType::TriangleList;

enum class は struct や class のようにクラスのメンバとして列挙定数が含まれるので、下手に名前空間を汚染することはありません。

1
PrimitiveType primitiveType = PrimitiveType::TriangleStrip;

“kTriangleList” のような余計なプリフィックスをつける必要がなくなり、補完やインテリセンスも気持ちよく利きます。

また、enum による列挙型では厳密な型チェックが行われていませんでした。

1
2
int const primitiveType1 = kTriangleList; // ok
unsigned char const primitiveType2 = kTriangleList; // ok

C++11 で導入された enum class では、型安全(type safe)なコードを書くのに適しています。

1
2
int primitiveType1 = PrimitiveType::TriangleList; // error
unsigned char primitiveType2 = PrimitiveType::TriangleList; // error

もちろん std::size_t に代入するのもダメです。

1
2
std::size_t primitiveType3 = PrimitiveType::TriangleList; // error
PrimitiveType primitiveType4 = PrimitiveType::TriangleList; // ok

enum class では列挙定数の型も指定できるので、今までの enum よりも、より型を意識したコードを書くことができます。

1
2
3
4
enum class PrimitiveType: std::size_t
{
TriangleList = -1, // error, Enumerator value evaluates to -1, which cannot be narrowed to type 'std::size_t'
};

事前にコンパイルエラーとしてミスを発見できれば、変なランタイムエラーに悩まされることもありません。C++11 ではこうした静的な型を意識したコードが、より短く簡単に書けるように進化しています。また次もこうしたお話ができれば良いと思います。(今日で連載終了かもしれません。)

少しでも C++11 に興味を持っていただけたら嬉しいです。


テーマ上、さくっと読んですぐ使える部分に的をしぼって書いています。置いてけぼりにしている仕様や詳しい話を知りたい場合は、次もぜひ参照してみてください:

http://isocpp.org/
http://www.boost.org/

誤字脱字、またはよろしくない部分などありましたら、コメントにてお願いします。

(趣味の話)これから新しく開発用デスクトップパソコンを買うなら。

おひさしぶりの投稿です。
今日はゆるやかに偏った趣味の話を書きます。(個人の趣味が大半を占めているのでお気をつけて!)

毎年、新入生の半数が大学生協からカスタマイズされたノートパソコンを購入します。
このノートパソコン(通称;生協PC)について、その筋に詳しい人(通称;パソコンの先生)から「もっと安くていいのあるのに〜〜」という声も毎年ちらほら聞こえてきます。

生協PCを購入する新入生と保護者の方の気持ちはよくわかります。入学前のほとんど大学生活のことを何も知らないときに、(もっとも入学前に頼れる存在である)大学生協さんがガンガンお勧めしてくるのです。「ほかの学生も全員購入してるかも」「授業で使うかも」などなど、いろんな不安にあおられて、とりあえず購入してしまうのです。
いざ大学生活が始まると、「生協PCである必要がなかった」「そもそも自分のパソコンを講義で使う機会がない」と知らされるので、購入した人の中にはちょっとガッカリしてしまう人もこれまたちらほらいます。

IBM 5100 の時代に比べるとだいぶ安くなりましたが、それでもパソコンというのはお高い買い物です。最近は1〜3万円台くらいのラップトップや、タブレット PC もでてきて手軽に買うこともできますが、コンビニでお菓子を買うような手頃さではありません。

さて、いろいろ家で開発したい面倒くさがり屋向けの PC を買うならどんなデスクトップパソコンを買うのがいいでしょうか?これが今日の本題です。
いろいろ模索してみましたが、自作PCでカスタマイズしまくり〜なんてのは、面倒くさがりな人には向きません。「グラフィックスボードはこれがいい!CPUはこれがいい!マザボはこれ!ケースはこれ!」と選ぶのが好きな人には自作PCはオススメです。ただ面倒くさがり屋さんには出来合いのPCがおすすめです。

そこで、面倒くさがりな人にお勧めしたい出来合いの開発用デスクトップはこちらです:
「Mac mini(竹) + Windows 8 Pro(Bootcamp)」

ちょっと前の時代であれば、Windows の入ったデスクトップPCを買って、Visual Studio .NET 2003 を使い、Visual Basic でアプリ開発を楽しむ大学生がほとんどでした。それが今や、時代が進むにつれ、個人開発もさまざまになってきました。たとえば、iOS アプリ、Android アプリが顕著な例です。
Android アプリに関しては「30 億のデバイスで走る ジャバ(JAVA)」のおかげで、OS を問わず Linux, Windows, Mac OSX などで開発することができます。
しかし、iOS アプリに関しては、Mac OSX 上でしか開発することができません。追い打ちをかけるように、最近の Mac OSX は OS のインストールディスク単体での販売を行っていません。
ということは、iOS アプリあるいは OSX アプリを開発したい人は Mac 製品を購入するしかありません。
幸運なことに最近は、Mac OSX 上で Bootcamp という機能がサポートされました。Bootcamp を使うと、OS のデュアルブートがいとも簡単にできます。この Bootcamp の機能を使って、Windows 8 Pro を超絶簡単にいれることができます。
なので、Mac mini と Windows 8 Pro のインストールディスク(オンラインでも購入できます)を買えば、Mac OSX と Windows 環境を1台で、いとも簡単に実現できちゃいます。これがもっとも、楽な方法です。

なぜ Macbook Air や iMac ではなく、Mac mini なのでしょうか。Mac mini は比較的安価で、そこそこ優秀です。サイズも小さく場所もとりません。見かけもそこそこオシャレなのでインテリアとしてもグッドです。持ち運びも楽なので、旅先で重宝します。Macbook Air と iMac にはディスプレイがついてますが、ディスプレイは特にいらないので Mac mini です。
また、Macbook Air で iOS シミュレータを長時間起動していると、突然クーラー音がなりだし、キーボード部分が熱を持ち始めます。キーボードが鉄板のように熱くなるので、とても開発できる状態ではありません。そう考えると、ディスプレイは BenQ などが出してる安価なものを、キーボードは HHK や赤軸キーボード、あるいはリアルフォースなどを買って、ぺぺぺぺっとくっつけるのが落ち着くのではないか、と心に抱いております。

Visual Studio 2012 はインテリセンスが効いてとても気持ちよく開発することができる一方で、コマンドラインの作業は unix や linux のコンソールでの作業が楽だったりします。もちろん、Windows 環境でそれっぽいコンソール環境を作ってパッケージをビルドしたり、ライブラリをビルドしたり、ランタイムエンジンをビルドしたりすることはできますが、作業がスムーズになるかというと難しいところです。nix のコンソールを触る場合は、nix の OS を入れて作業するのが、一番面倒くさがりな人には向いているのではないでしょうか。Windows でコマンドラインの作業を行うなら、無難に PowerShell を使って PowerShell の良さに触れるのが最も楽しいです。

ということで、「Mac mini(竹) + Windows 8 Pro(Bootcamp)」が個人的におすすめです。
Mac mini はメモリなどのカスタマイズも簡単にできるので、通販で安くメモリを買って付け替えるのも容易いです。
生協PCの価格くらいで、Mac mini(竹) + Windows 8 Pro + メモリ + ディスプレイを買えるので、結構いい感じの環境が作れます。

もちろん学生さんはお金がないので、地道にがんばってお金のかからない最高の環境を作るのがライフワークなのですが、面倒くさがり屋さんでそこそこ余裕があったらお金で解決しましょう。
「できなくはない」ってことはいっぱいありますが、まずは「やりたいこと」を明確にして、そのやりたいことへの近道を模索するのが開発で重要なことだと思います。Windows 上で無理やりがんばって iOS アプリ開発環境を作るのが「やりたいこと」であれば、がんばってコンソール環境作るのもいいかもしれません。「iOS アプリも Windows Store アプリもどっちも作りたい」と思ったのであれば近道しましょう。

たまには出来合いのものですませるのも一つの手だと最近知りました。


(ちなみに C3 では OSX, Windows 8 環境をそろえています。今年は OSX アプリをリリースしてみたいです。)

新入生の皆さんへ

C3に興味を持っている新入生の皆さん、こんにちは。ADANという若輩者です。

私たちC3部員は皆さんの入部を歓迎します。

入部していなくても、部室へ気軽に遊びに来てください。

C3の部室はサークル棟の2階、階段を上って右奥隅です。扉にはサークルのロゴが貼ってあるので一目でわかります。ちなみにサークル棟は体育館のミニグラウンドを挟んで向かい側にある建物です。

部室の開閉状況と部会の日時はC3のサイトのトップページ下側で確認できます。開閉状況については外からでも確認できるように段ボールの板をプレハブの上にある2階の窓にロゴと共に立てかけてあります。○になっていれば誰か部室にいますので遊びに行きましょう。×だったら部室には中に誰もいませんよ。○になるまで待ちましょう。

サークルについて気になることがあれば些細なことでもかまいません、ぜひ部室に質問しに来てください。何でも答えちゃいます(パスワードとかはさすがに無理ですが・・・)。

まあ、来れば分かります。他のサークルにも脇目を振りつつ、C3に突撃してください。

第52回工大祭も間近に迫ってます♪

おはようございます!yokoです。

さて早いもので今年も、この時期がやってきました!
そうです!第52回工大祭が、もうまもなく開催です♪

11月24日(土), 11月25日(日)の 2 日間にわたって開催されます。飯塚キャンパスの工大祭について詳しく知りたい方は、下記のページをご参照ください:

C3 では今年もなんとなんと…「模擬店」と「サークル展示」を行います!!

サークル展示では、部員が1年間(あるいはそれ以上!?)かけて作ったゲームや音楽、3D モデリングなどの作品を展示します。そして今年も、作品をぎゅっとひとつにまとめた作品集 CD を配布しちゃいます!!(もちろん無料です♪)

今年は例年の反省をいかして、CD 製作班の指揮のもと早い段階から製作にとりかかったため、『すごい出来』になりました!CD 名はなんとなんと…「new C3」です!(delete しちゃダメですヨ~~)
過去に前例のない大層なタイトルの CD を頒布しちゃいますが、中身のほうもしっかりトンデモナイ出来になっており、新旧作品含めて部員の熱い『魂』がこれでもかというほどに詰まってます。ぜひ、サークル展示会場でお手にとっていただけると幸いです。(数量限定 100 枚の頒布なのでお早めに)
サークル展示の場所は、「1104 講義室」で行います。ぜひお越しください♪

また模擬店もやっちゃいます!模擬店の配置は去年と異なっております。工大祭実行委員会のウェブページで公開しているグラウンドの見取り図がわかりやすいのでリンク先をご参照ください:

上記のページにおいて、C3 は「コシヒカりん」(配置番号 6)というお店を出店しています。ちなみに、「居酒屋」は「配置番号47」となっております。今年は少々離れてしまいましたが、C3 にも居酒屋にもお気軽に顔を出していただけると幸いです。部員一同、楽しみにお待ちしております。

工大祭も間近に迫ってきましたが例年気になるのは、お天気です。天気予報を見ると、ちらほら曇り空マークが見えます。天気がくずれなければいいですが、ふとした拍子に天気がくずれることもありますので、工大祭を訪れる際には空模様の確認と雨具の携帯をするとよさそうです。

さて、明日は工大祭の準備日です。・・・そしてそして、明後日からついに工大祭です!!一般の参加者の方も、OB の方もぜひぜひ、模擬店・サークル展示へお運びください。
では、皆さま、明日から3日間乗り切っていきましょう!

へっくしゅん!!!

目が覚めたら、工大祭前でした。

(チュンチュン…チュンチュン…)

小鳥たちが鳴いている。そうか、朝がきたんだネ。ぼくたちの「新しい朝」が…。
昨日は夜遅くまで、デバグをしていたんだ。その証拠にほら、Visual Studio がブレエクポイントで止まったままになってる。きっと寝落ちしたんだネ。

大きなあくびをし、ふと iPhone(アイフォーン)を手に取ってその日付に驚いた。
「もうそんな日か…。」

そう、今日 11月22日(木)は、ぼくたち C3 が敬愛するビートルズの 10 枚目のアルバム『ザ・ビートルズ』が発売された日だった。こんな朝には、『オブ・ラ・ディ、オブ・ラ・ダ(Ob-La-Di, Ob-La-Da)』がお似合いだね。軽快な南米のリズムに、ポールの声がはずむように重なる。レコードから流れるリヴァプールのサウンドについつい夢中になって、時が過ぎていくのも忘れていた。

ふと我に返ると、大事なことを思い出した。
「明日 11月23日(金)は、工大祭準備日だ…。」

豊かな暮らしと日々の生活の中で、ぼくたち人類が、忘れかけていた大切なコトを思い出せたよ。
Ob-La-Di, Ob-La-Da…

WindowsでopenGLを使う

こんにちは、BISです。
kyutechの学生さんも夏休みに突入したと思われますが、皆さんいかがお過ごしでしょうか?
自分はPSPで遊んで、SICP読んで、schemeスゲェしながらC言語でプログラミングをしております。

それはそうと、今日の話題はOpenGLです。
しかも難しい応用の話題ではなく、スタートアップの話です。

Windowsでゲームを作るときはたいていDirect3Dを利用すると思います。
しかし、宗教上の理由とかマルチプラットフォーム狙いとかでOpenGLを使いたいという人もいるのではないかと思ってこの話を記事にしてみることにしました。

というのも、自分はLinuxでゲーム開発していますが、最終的にはWindows環境でも動作するようにしたかったのでWindows上での開発環境を整えていました。
その途中で環境による違いでいろいろと面白ツールとの出会いがあったわけです。
UnxUtilsとかMinGWがどうとかsconsがどうとか色々ありますが、今回はOpenGLのお話です。

話は戻りますが、実はWindowsは標準でOpenGLをサポートしています。
おもむろにエクスプローラを開いて、以下のアドレスをファイルが無いか探してみましょう。

C:/Windows/System32/opengl32.dll

ネーミングセンスには疑問を覚えますが、それでもWindowsがOpenGLを標準でサポートしているのは良いことです。
で、実際使おうと思うとやっかいな事がわかります。OpenGLのバージョンが低いのです。
正確にどの程度までサポートしているかは調べれば分かると思いますが、OpenGL1.1相当だと思われます。
これではOpenGLでやりたいことの半分もできません。
今のOpenGLのバージョンは4.3とかそれくらいなのに!
(最近のOpenGLは頻繁にバージョンアップをしているので、定期的に確認したほうが良さそうですね)

そこで登場するのが、wglという機能です。
wglとは、WindowsのopenGL拡張で、主にWin32APIといった主要なAPIとOpenGLのレンダーコンテキストとの橋渡しを行う機能群です。
詳しい話はMSDN “MSDN”)でも読めば分かります。
もうレガシーな機能なのであんまり推奨はしたくないですけど、わざわざOpenGLもどきを作る作業なんて御免ですから使ってしまいましょう。

重要なのは、wglGetProcAddressという機能です。
これはシステムがサポートしている拡張関数を取得してくるという機能で、これを利用すれば(ハードウェアがサポートしているなら)OpenGL1.1以上の機能を利用することができます。
使い方は簡単で、使いたい関数名を文字列として引数に渡したら、システムに存在している機能なら関数ポインタが返ってきますので、あらかじめアプリケーション側で用意しておいた関数テーブルに代入していくだけ。
これを実際に機能を利用するまでに実行しておけばよいのです。

面倒ですね。

こういった定型作業はだれかがすでにライブラリ化しているはず。
で、登場するのがGLEWというGLで拡張機能を利用するためのラッパーライブラリです。

GLEW

こいつを利用すれば、なんとglewInit()を呼び出すだけで利用できる拡張関数を読み込んでます。
あとはヘッダに用意された関数テーブルを利用するだけで簡単にOpenGLが利用できます。
さらにGLEWはオープンソースで、コンパクトで、主要なOSほとんどをサポートしていて、さらに環境構築が面倒なWindowsのために、コンパイル済バイナリまで用意してくれているという親切丁寧ぶりです。
ここは利用させて頂くほかないでしょう。

このwglGetProcAddressをラップしたglewInitは呼び出すタイミングがあるので、一応書いておきます。
この拡張関数を取得する機能はGLの描画コンテキストが無いと利用できません。
ので、この関数を呼び出すのはGLの描画コンテキストを作ってからです。
glutならCreateWindow後、sdl2やwglならMakeCurrent後に呼び出すようにして下さい。

自分はsdl2と併用しているのですが、それっぽいコードを書いてみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include &lt;SDL2/SDL.h&gt;
#include &lt;GL/glew.h&gt;
int main()
{
SDL_Window *win = NULL;
SDL_GLContext ctx = NULL;
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
return 0;
}
atexit(SDL_Quit);
win = SDL_CreateWindow(
&quot;test&quot;,
10,
10,
320,
240,
SDL_WINDOW_OPENGL);
ctx = SDL_GL_CreateContext(win);
/* 描画コンテキストの設定 */
if(SDL_GL_MakeCurrent(win, ctx) != 0)
{
return 0;
}
/* このタイミングで使わないといけない */
if(glewInit() != GLEW_OK)
{
return 0;
}
/* MainLoop? */
while(1);
/* 後始末 */
SDL_GL_DeleteContext(ctx);
SDL_DestroyWindow(win);
return 0;
}

気分はこんな感じです。
これであなたのWindowsでもOpenGL4.3とかが自由に使えるでしょう。
おっと、ハードウェアがサポートしていないとどうしようもないので、グラボのメーカーページに行って最新のドライバーをインストールしておくことお忘れなく。

あなたがもしLinuxやそれ相応のOSを利用しているなら、Mesa3DのようなしっかりしたOpenGL準拠のグラフィックスライブラリがあるので、拡張読み込みのようなことをしなくてもOpenGLの上位のバージョンを利用することができます。
しかし、Windows環境に移植が容易なソースコードを用意しようと思うなら、GLEWを利用したコードにしておくと移植が簡単になるので便利ですよ。

それでは良いOpenGLライフを。

(内部向け)今年はやります!!yokoプレゼンツ・絵日記大会~2012夏。

もう、8月も目前に迫ってきました!!
そうそう、C3 の夏の風物詩といえば…

そう、「絵日記」です!!

ふと「夏休みだし絵日記を描いたら面白そう」と思ったので夏休みはみんなで絵日記を描きましょう。
以下は、すべて私 yoko の独断で勝手に部内でイベントを開催させていただきます。


【絵日記大会~2012夏】
8 月いっぱいを使って、絵日記を書きます。最終的に夏休み明けに絵日記帳を集めて、ぱらぱらっと見て、独断で「これ面白い!」と思った絵日記の作者の方に、「ぼくがもらって嬉しい賞品」(Am○zon ギフト券?)を進呈します。

参加資格は「絵日記帳」または「じゆうちょう」を持っている部員であれば、誰でも参加可能です。スーパーに「えにっきちょう」はなかなか売ってないので、文房具店・本屋さん、あるいは通販などで買いましょう。
通常のキャンパスノートなどでもかまいませんが、減点対象になるかもしれません。Kobo は不可です。逆に「低学年用えにっき」や「色えんぴつ」などの雰囲気が出るアイテムであれば、ポイントに加算されることもありうるかもしれません。よりそれっぽいノートであれば望ましい限りです。このへんはみなさんのセンスにまかせます。表紙に名前を書くのを忘れないでください。

期間は 8月1日から8月31日です。その間、毎日絵日記を描いてもらいます。もちろん大学生ですし、なおかつ「夏休み」です。当然、飽きるでしょう。大丈夫です、飽きてもいいんです。日記を書かなかった日は、次の日にでも書くか、空白のまま飛ばすかしてください。それも「夏休みの絵日記」特有の醍醐味です。ノートの購入などで出遅くれて、8/1 のスタートに間に合わなくてもかまいません。とにかく夏休みの 8 月いっぱいを使って、皆さんのアイデアが光る楽しい絵日記を書いてください。
内容はできる限りノンフィクションが好ましいですが、フィクションを織り交ぜたり、話を盛ったりしてもかまいません。このへんもみなさんの「センス」におまかせします。

審査で見る点は:
・いかに「夏休みの絵日記」っぽい雰囲気が醸し出てるか
・8/1 から 8/31 の全体を通して、面白いかどうか
・センスがキラリと光っているか
・どことなく大学生っぽいか
・3日坊主で終わってるか

など各エキスパートの分野から鋭いマルチな視点で作品を評価(レビュー)します。

審査は、主催者の独断とその場のノリで行います。みんなで回し読みをしてどれが面白いかなどの意見をきいたあとに、「じゃあこれ!」みたいなゆるい感じで優勝者を決める予定です。参加者が誰もいなければ、主催者の私が優勝となります。
ふるってご参加ください。夏休み明けの部会でノートを回収するので、暇な人は「えにっきちょう」を購入してさっそく書き始めましょう。ノートの返却を希望する人は回収するときに伝えてください。


以上、私がいまさっき思いついたイベントです。夏休みはあっという間なので、絵日記でも書いて1日1日を振り返る癖がつけばいいな、と考えています。

さて、絵日記がなぜ、今のソフトウェア開発で重要視されているのかは言うまでもありません。
ソフトウェア開発の中で、週報や日報、あるいは作業ログをつけるのが非常に大切だと感じました。週報でなくとも、TODO リスト(あるいはチケット管理)や、実装までのマイルストーン表示、あるいは git のコミットログなど、作業の流れを確認しながら作ると、「動くソフトウェア」を早く作るために「いま何をすべきなのか」を明確にすることができます。寄り道したり、道しるべを見失うことがありません。そして、これらの能力は「夏休みの絵日記」によって強化することができると言っても過言じゃないです。

ということで、お暇な部員のみなさん、参加してください。もちろん、このブログの記事を見てしまったら、さっそく「えにっきちょう」を購入している人が大半を占めていると思います。夏休み明けがとても楽しみです!