Lyの日常

主が楽しくプログラムをカキカキするブログ

C++ネットワークライブラリを作成した件について

どうも
オンラインゲーム作ろうとして
ネットワークを勉強し始めて
泥沼にハマった僕です

プロトコル

ネットワークを通じてデータの送受信に
決められたプロトコル(TCP, UDP)が存在します

TCP

は、データの届く順番を守ったり
データが届いていない際は再送したりと
保守性のあるプロトコルです

UDP

は、TCPとは真反対で
データの届く順番を保証せず
データが壊れてもお構いなしのプロトコルです

しかし、保守性のない分TCPより速度が出ます

ゲームにおいて

TCPはデータの保守性から
チャットやアイテムなどのデータのやり取りに使われます

UDPは速度が出るので
FPSなどのリアルタイム性を求めるゲームなどで、位置情報のやり取りに使われます

作成したライブラリを置いてみる

既存のライブラリがクロスプラットフォームじゃなかったり
何かと使い勝手が悪かったので自分でつくってみました

TCPライブラリ
github.com


UDPライブラリ
github.com

(:3

上のライブラリでローカル上であればすんなり通信ができる
でも家庭にはルーターという魔物が存在して
そいつのせいでインターネットを介した通信になると途端に難易度が上がる
そのことについては後日記事にします、ω、

FreeTypeのバージョンを2.6.3に!

お久しブリブリ
Freetypeのバージョンを上げたので
その時のお話しでも、ω、

僕はFTGLを介してFreeTypeを使用してるので
中身がどう変わったのかはわかりませんが・・・

includeファイルの構成がすっきり!

以前までは
このようにfreetypeフォルダを指定しないといけませんでした
f:id:akira206:20160308173731p:plain

それが指定しなくてよくなったんです!
f:id:akira206:20160308173824p:plain

これでCMakeListsがすっきりしました

解凍

f:id:akira206:20160308174302p:plain

ビルド用フォルダを作成

僕はWindowsで使用するのでVS2015という名前にしました
f:id:akira206:20160308174456p:plain

CMake

CMakeをインストールしたターミナルソフトで
まずはvs2015に移動します

cd freetype-2.6.3/vs2015

次にcmakeを実行します
Win32でビルドしたい場合は

cmake ../

でおk

Win64でビルドする場合は

cmake -G "Visual Studio 14 2015 Win64" ../

という風にします
*VS2015の場合

ビルド

f:id:akira206:20160308175106p:plain
開始できません
のエラーは正常終了の合図(?)
重要なのは
画像左下の「失敗」が0であることです

そのままビルドが終了すれば
freetype-2.6.3/vs2015/Debug
の中にfreetyped.libが出来上がっているはずです

Let's enjoy!

Mac用のバイナリも用意せねば・・・

CMakeでプロジェクト作成!

どうも、ω、
みなさんCMakeって知ってますか?

僕は今までLinuxvimを使ってコードを書いて
Makefileを作って
ソースコードコンパイルしてました

// こんな感じに
$ make run

めんどくさいコンパイルオプションを打たなくて楽でした
そう、一人で開発をするなら・・・

チームで開発する際には
Xcode, VS, Eclipseといった複数IDEが混合します

ソースコードを追加したり削除したとき
vsで消して、Xcodeで消して、Eclipseで消してと
とてもめんどくさいです

CMakeはそんなめんどくさい作業を引き受けてくれます

CMake導入

// osx
$ brew install cmake +gui

// linux
~$ sudo apt-get install cmake

// winows
おとなしくgui

パッケージマネージャーのお話
osxならhomebrewが定番?です
linuxならディストリによって変わりますが
debian系ならapt-getですね
windowsは最近パッケージマネージャが導入されたとかなんとか
正直guiを使った方が楽かもです

CMake使い方

下準備

実はxcodeのプロジェクト作成が成功してすぐ記事を書いてるので
理解が浅い部分が多々有ります

プロジェクトとなるHogeフォルダを作ります
Hogeフォルダの中には
xcode (空
・CMakeLists.txt
src
 ∟ main.cpp
 ∟ CMakeLists.txt
f:id:akira206:20160131074031p:plain

# Hoge/CMakeLists.txt

" cmakeのバーション指定
cmake_minimum_required(VERSION 3.4)

" プロジェクト名の指定
project (hello_project)

" サブディレクトリの追加
add_subdirectory( src )


# Hoge/src/CMakeLists.txt

" コンパイルオプションの指定
set( CMAKE_C_FLAGS "-Wall -g" )

" GLOB SRCSがわからないけど
" フォルダにある.cpp .hppのつくファイルを指定してることはわかる
file( GLOB SRCS *.cpp *.hpp )

" プロジェクト内でのsrcフォルダの名前
add_executable ( hello ${SRCS} )

実際に使ってみる

# ターミナルから

" xcodeフォルダに移動
~$ cd Hoge/xcode
" cmake実行
~$ cmake .. -G "Xcode"


# guiから
ソースはHoge
ビルドはHoge/xcodeを指定する
f:id:akira206:20160131075700p:plain

Configureをクリックしてプラットフォームを指定
f:id:akira206:20160131075844p:plain

ビルドが終わったらこんな感じになるので
Generateをクリックして完了
f:id:akira206:20160131080017p:plain

プロジェクトの起動・ビルド

cmakeが終わるとプロジェクトが生成されます
f:id:akira206:20160131080135p:plain

ソースコードがあるのが
helloになるのでhelloを指定すればビルドが通ります
f:id:akira206:20160131080507p:plain

シェーダーたのじいいいいいいいい!(二日目

どうも、ω、
今日はこんなかんじのを実装してみたいと思います
f:id:akira206:20151219220820p:plain
光の玉みたいな。ω。

まずは点を描画してみる!

以下のコードで画面の中央に点がでればおk、ω、
f:id:akira206:20151219220528p:plain

どうなっとるんや!?

// 画面の中央座標を取得
vec2 center = resolution * 0.5;

resolutionは画面のサイズでした
その値を[ * 0.5 ]つまり半分にした値が画面の中央座標になるわけです
たとえば横幅400、 縦幅200の場合
[ * 0.5 ]をすれば[200, 100]の値がとれるわけです!

// 最終的な色を決める変数を用意
// 黒で初期化
vec4 color = vec4(0.0);

そこまんまですね
いろいろ計算して1ピクセルの色を決定しますが
その最終的に決まった色をこの変数に格納させます、ω、

// 現在計算している座標(gl_FragCoord.xy)から
// 画面の中央(center)との距離を求める
float dist = length(gl_FragCoord.xy - center);

length関数はvec2型を引数にとり
返り値がfloatとなってます

すこし図にかいてみるとみえて・・・
f:id:akira206:20151219214149j:plain
みえ・・・みえ・・・見えるぞ!

ようはvec2の値をfloatに変換してるだけですね、ω、

// 最終的な色に足しこむ
color += dist;

distは距離でした
距離が一番近い値で0.0で
すこしでも離れると値が増えていきますね
なぜこれで点が描画されるのか
図に書いてみてみましょう
f:id:akira206:20151219215654j:plain
みえ・・・みえ・・・見えるかもしれない・・・?

光の強さ(色)は0.0~1.0で表すので
1.0を越えた時点で真っ白になります
なので距離が0,0にちかい一点のみ黒くなるわけですね

そろそろかっちょいいの出そう!

f:id:akira206:20151219221509p:plain
おほおおおおおお!!

追加点

float size = 5.0;
color += (size / dist);

sizeは言わずもがなサイズです
玉のサイズにあたる部分です

さて、サイズ / 距離 でこんな演出がなぜできるのでしょうか?

distは離れるにつれて数値がでかくなります
ためしに小さい値から順に5.0を割ってみましょう

5.0 / 0.1 = 50
5.0 / 0.5 = 10
5.0 / 1.0 = 5
5.0 / 1.5 = 3.333...
5.0 / 2.0 = 2.5
5.0 / 2.5 = 2

図で表すと・・・
f:id:akira206:20151219222314j:plain
図が下手ですみません、ω、
もうすこし急なカーブを描くと思います。ω。

つまり近いほど値が(光の強さ)大きく
離れるにつれてゆっくりと値が小さくなるわけです

綺麗な玉が描画できた!((いみしん

今日はここまでとします、ω、
ほんとはブラーまでいきたかったけど
次回に持ち越しです。ω。

それではよいコーディングライフを!ノシ

シェーダーたのじいいいいいいいい!

どうもみなさんこんちくわ、ω、
ちょっとシェーダーってものを触ってみました
今こんなものが出来てます

f:id:akira206:20151212093246p:plain
f:id:akira206:20151212093423p:plain

シェーダー??

シェーダー(英: shader)とは、3次元コンピュータグラフィックスにおいて、シェーディング(陰影処理)を行うコンピュータプログラムのこと。
((wiki参照

どんなロジックなんじゃらほいほい?

やってることは単純で
1ピクセルの色を計算して画面に描画する
ということをやっています

さっそく始めてみる

今回僕はGLSL Sandbox Galleryこちらのサイトを使用しました
なんでもコードを打ちながら結果が見れる優れもの、ω、

サイトに飛んだら
Create new effect! をクリック!

なにやらウニャウニャしてますが
とりあえず以下のコードを書いてみましょう

#ifdef GL_ES
precision mediump float;
#endif

void main() {
  gl_FragColor = vec4(1.0);
}

f:id:akira206:20151212095047p:plain
真っ白になったと思います。ω。

とりあえず上の3行は呪文とします。ω。((僕わからない

gl_FragColor...?

こいつが1ピクセルの色データです
型はvec4で
red, green, blue, alpha
を示します

  gl_FragColor = vec4(1.0);

このコードで現在計算しているピクセルの色を白にしています
どのピクセルも白にしているので全画面真っ白になるわけです。

uniform...?

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main() {
  gl_FragColor = vec4(1.0);
}

uniformで宣言している変数は外部変数としてすでに用意されているもので
timeはデルタタイム
mouseはマウスの位置
resolutionはウィンドウの横幅と縦幅となっています

sin cos...もつかえるで!

#ifdef GL_ES
precision mediump float;
#endif

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main() {
  gl_FragColor = vec4(sin(time));
}

みんな大好きsinちゃん
画面が白くなったり黒くなったりすると思います、ω、

gl_FragCoord...?

int main() {
  // 色用変数を用意して黒で初期化
  vec4 color = vec4(0.0);

  // 画面の半分から右側を計算しているときは白色とする
  if (gl_FragCoord.x > resolution.x * 0.5) {
    color = vec4(1.0);
  }
  gl_FragColor = color;
}

f:id:akira206:20151212104000p:plain

お?
なんか一色端ではなく半分に色が分かれましたね、ω、
いままで1ピクセルの色を計算と言ってきましたが
今どこのピクセルを計算しているのだろう??
ってときに使うのがgl_FragCoordです!
現在計算しているピクセルの位置を取得できます、ω、

長くなりそうだから今日はここまで!

次回はマウスの座標取得から入りたいと思います、ω、

Win/Mac チャットできるコンソールアプリケーション作った!

ドウモ ド=クシャ さん

オンラインゲームが作りたくて
通信の一歩としてチャットアプリを作成したので
記事を書いていきます、ω、

参考にしたサイトはこちら

TCPプログラミング
こちらのサイトは一つ一つの関数について深く述べています
すこしデータが古いのが難点

Geekなぺーじ:プログラミング
とりあえず動くサンプルコードがあります
Win/Mac対応

いつものごとくGithubにあげてます

github.com
開発環境
Win:C++ vs2013
Mac:C++ xcode7.1

通信プロトコル

TCP (Transmission Control Protocol)
現在使われているインターネットの通信の90%は
TCPによるものだと言われているらしい

TCPはコンピューター間に仮想回線をつくり、通信を行うプロトコル
通信失敗時には再送し、受信順番と送信順番を保証します

UDP(User Datagram Protocol)
信頼性のない通信プロトコル
その分通信コストが低くリアルタイム性のある通信が可能

TCP/UDPのどちらも言語やプラットフォームに左右されないのが強みです

今回はチャットアプリを作成しようと思うので
TCPを採用しました

ソケット(Socket)

PC間で通信する際にデータの受け渡しをする者が必要になります
それをソケットと言い、TCP通信のことをソケット通信と呼ぶことがあるようです

Server側は窓口(Socket)で
Client側は訪問者(Socket)みたいなイメージですね

通信の流れ

Server側

# コードはMac時のものです
[1] ソケット作成

int sock;
sockaddr_in addr;

// ソケット作成
sock = socket(AF_INET, SOCK_STREAM, 0);

// ソケットの設定(Server自身の)
addr.sin_family = AF_INET;
addr.sin_port = htons(37951); // *1
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_len = sizeof(addr);

// 設定した内容をソケットに結びつける
bind(sock, (sockaddr *)&addr, sizeof(addr));

// クライアントからの接続を待てる状態にする
listen(sock, 5); // *2

[2] 通信先と接続

sockaddr_in client;
int client_sock;
auto len = sizeof(client);

// 通信を許可
client_sock = accept(sock, (sockaddr *)&client, &len);

[3] データ送受信

// 文字列を送る
write(client_sock, "Wellcom!", 8); // *3

[4] ソケット封鎖

close(client_sock);
close(sock);

// *1 ポート番号は0~65535までと決められている
// *2 引数の5は最大接続人数、大きい数字にしてもOSにより制限されてしまうらしい
// *3 引数の8は文字数

Client側

[1] ソケット作成

int sock;
sockaddr_in server;

// ソケット作成
sock = socket(AF_INET, SOCK_STREAM, 0);

// 接続先を指定
server.sin_family = AF_INET;
server.sin_port = htons(12345);
server.sin_addr.s_addr = inet_addr("127.0.0.1"); // *1

[2] 通信先と接続

// サーバーに接続
connect(sock, (sockaddr *)&server, sizeof(server));

[3] データ送受信

char [32];
read(sock, buf, sizeof(buf));

[4] ソケット封鎖

close(sock);

// *1 アドレス127.0.0.1は自分自身を示しています

アドレスを適切なものに変更すれば他のPCと通信ができます、ω、

最後に

今回通信には特殊なライブラリなどは使用していません
一般的な開発環境(あいまい、ω、)ならすぐ始めれると思います

今回目標にしたのが
チャットアプリを作成している他の人のコードを読まずに完成させること
でした。
ググれば見つかるでしょうがせっかく初めての通信プログラムだったので
頑張ってみました、ω、

gitコマンドを使って他人のレポジトリにプルリクを送る方法-Mac

Unixコマンド - cd

cd <file>

cdコマンドで< file >まで移動ができる

たとえば現在Desktopにいるとして
DesktopにあるHogeフォルダに移動したい場合は

cd Hoge

逆にHogeから一つ戻ってDesktopに移動するには

cd ..

Unixコマンド - ls

ls

lsコマンドを使えば現在地にあるファイルをリストアップできる

たとえば今Desktopにいるとして
DesktopにHoge, Piyoフォルダが在る場合

ls           // lsと打った後Enter
Hoge   Piyo  // リストアップされる

Githubで他人のレポジトリをfork

f:id:akira206:20151122015839p:plain
Forkの部分をクリック

自分のForkしてきたレポジトリをclone

cloneでgithub上にあるファイルなどをPCに落として来れます

[自分のアカウント]/[レポジトリ]
レポジトリを開きます
f:id:akira206:20151122021558p:plain
HTTPSをコピーしましょう
コピーできたらターミナルに戻ります

ターミナルを開いたらlsコマンドを打ちます

ls
Desktop       // デフォルトの状態ならDesktopがあるはず

今回はDesktopにcloneしたいと思うので
cdコマンドで移動します

cd Desktop

cloneする際は git cloneコマンドを使います

git clone <URL>

URLの部分は先ほどのHTTPSでコピーしたものです

変更点をpushする

cloneしたものに変更点を加えたらpushします
まずはターミナルを開いてファイルまで移動します

移動できたらgit addコマンドで変更点をgitに対して追加します

git add <変更したファイル>

次に変更したものに対してコメントを残します

git commit -m "<file>を変更しました" // ダブルクオーテーションで括った文字列はなんでもおk

変更点をpushしましょう

git push     // or [git push origin master]

アカウント名とパスワードを聞かれた場合は
自分のアカウント名とパスワードを入力

自分のcloneしてきたレポジトリからプルリクを送る

f:id:akira206:20151122023542p:plain
このボタンからあとはガイドラインに沿っていけばプルリクを送れます