キャベツのおかわり2013/12/01

トンカツの「和幸」で客が残したキャベツ等を使いまわし

「和幸」にはときどき行くけど、自分の行った店ではおかわりキャベツの提供の仕方が違うからたぶん大丈夫…だと思いたい

それはそれとして

和幸に限らず、おかわり自由な店で店員がなかなか店に出てこないのは何とかならないものか

大きな声で呼ぶのも他のお客さんに迷惑だし、席を立って厨房入口まで行って「すいません」と呼ぶ羽目になる

店員がおかわりを持ってきてくれるような店は、テーブルに呼び出しベルを置いておいてほしい

フェードイン・フェードアウト2013/12/02

画面描画にはフレームバッファを使用しています(11/6の記事参照)。
最終的に画面に出すフレームバッファはテクスチャとして描画していますので、カラーを設定することができます。
このフレームバッファ描画時のカラーを変更することによって、画面のフェードイン・フェードアウトを実装してみます。


Renderer.h
	static GLubyte	screen_color[4*4];					// 画面描画カラー
	static int		fade_bright;						// 画面の明るさ
	static int		fade_speed;							// フェードの速さ

クラス sys::Rendererの静的メンバ変数です。
固定だったカラーバッファを変更できるようにしています。

	static void		fade_in(int _cnt = 500/FRAME_PERIOD)		// フェードイン
					{
						fade_speed = (_cnt > 0) ? (254 + _cnt)/_cnt : 255;
					}
	static void		fade_out(int _cnt = 500/FRAME_PERIOD)		// フェードアウト
					{
						fade_speed = (_cnt > 0) ? -(254 + _cnt)/_cnt : -255;
					}
	static int		get_bright(void)							// 画面明るさ取得
					{
						return	fade_bright;
					}

フェードイン・フェードアウトの関数です。
フェード時間をフレーム数単位で指定します。


Renderer.cpp
/********************
    描画(後処理)
 ********************/
void	Renderer::draw(void)
{
	if ( fade_speed > 0 ) {				// フェードイン
		fade_bright += fade_speed;
		if ( fade_bright >= 255 ) {
			fade_bright	= 255;
			fade_speed	= 0;
		}
		for (int i = 0; i < 4*3; i++) {
			screen_color[i + i/3] = (GLubyte)fade_bright;
		}
	}
	else if ( fade_speed < 0 ) {		// フェードアウト
		fade_bright += fade_speed;
		if ( fade_bright <= 0 ) {
			fade_bright	= 0;
			fade_speed	= 0;
		}
		for (int i = 0; i < 4*3; i++) {
			screen_color[i + i/3] = (GLubyte)fade_bright;
		}
	}


	static const
	GLfloat	_projection[4*4] =
			{
				1.0f, 0.0f, 0.0f, 0.0f,
				0.0f, 1.0f, 0.0f, 0.0f,
				0.0f, 0.0f, 1.0f, 0.0f,
				0.0f, 0.0f, 0.0f, 1.0f,
			};

	static const
	GLfloat	_texcoords[] =
			{
				0.0f, 0.0f,
				1.0f, 0.0f,
				0.0f, 1.0f,
				1.0f, 1.0f
			};

	static const
	GLfloat	_vertices[] =
			{
				-1.0f, -1.0f,
				 1.0f, -1.0f,
				-1.0f,  1.0f,
				 1.0f,  1.0f,
			};

	ShaderProgram*	_shader = use_shader(SHADER_TEXTURE);

	// フレームバッファテクスチャ描画
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glViewport(screen_rect.x, screen_rect.y, screen_rect.w, screen_rect.h);
	glUniformMatrix4fv(_shader->projection, 1, GL_FALSE, _projection);
	glBindTexture(GL_TEXTURE_2D, frame_buffer->texture);
	glVertexAttribPointer(_shader->texcoord, 2, GL_FLOAT, GL_FALSE, 0, _texcoords);
	glVertexAttribPointer(_shader->position, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
	glVertexAttribPointer(_shader->color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, screen_color);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

描画前に明るさの変更を行い、カラーバッファに値を設定します(249~268行)。
フレームバッファテクスチャ描画で、設定したカラーバッファを指定しています(307行)。


サンプル
AppMain.cpp
/******************************
    稼働
		戻り値	アプリ続行か
 ******************************/
Bool	update_app(void)
{
	sprite[SPR_PHOTO].draw(0.0f, 0.0f);					// 背景
	for (int i = 0; i < 4; i++) {						// ビー玉
		int		t = ((cnt + i*15) % 60) - 30;

		sprite[SPR_BALL_BLUE + i].draw(((i*180 + cnt*4) % 720) - 360, 400 - (30*30 - t*t)/2);
	}
	cnt++;

	if ( sys::TouchPanel[0].flag & sys::TouchManager::TRIGGER ) {
		if ( sys::Renderer::get_bright() == 0 ) {
			sys::Renderer::fade_in(60);					// フェードイン
		}
		else if ( sys::Renderer::get_bright() == 255 ) {
			sys::Renderer::fade_out(60);				// フェードアウト
		}
	}

	return	TRUE;
}

画面をタッチすると、現在の明るさに応じてフェードイン・フェードアウトを行います。


プロジェクト一式は、こちらから。

流行語大賞2013/12/03

今年は流行語になるようなものがいろいろあったので、いったいどれが大賞になるのかと思っていたら4つも受賞。
なんだ1つに絞るんじゃないのか…と、ちょっと肩すかし。


じぇじぇじぇ
「あまちゃん」を全然見ていないので今ひとつニュアンスがわかりませんが、キン肉マンにおける「ゲェー!!」みたいなものでしょうか?

お・も・て・な・し
パロディで他の5文字の言葉を真似して言う人がいたりしますが、普通の会話にはさむにはテンポが悪いんですよね。

今でしょ
自分で使うことはありませんが、普通に「いつ?」と聞いただけなのに嬉々とした顔で「今でしょ!」と返してくる人はうっとうしい。

倍返し
ドラマ「相棒」でも使われていました。ずいぶん前の話(金庫を開けるために亀山が監禁されるやつ)ですが。
言葉自体よりも物真似が流行った感じです。


むしれるだけむしる
アカギ 1

アカギ 1
著者:福本伸行
価格:420円(税込、送料込)
楽天ブックスで詳細を見る


こっちは「倍プッシュ」

端末解像度はさまざま2013/12/04

アプリの画面の大きさは def.hの SCREEN_WIDTH、SCREEN_HEIGHTで定義され、実際のAndoroid端末の画面に合わせて拡大・縮小されて表示されます。しかし、アプリの定義と端末で画面の比率が合っているとは限りません。

例えばアプリの画面が3:4に対して端末の画面が9:16の縦長の場合、描画の上下はカットされ黒い帯となります。

今回は、端末に合わせるための画面サイズと、内部で描画できる画面のサイズを別に持って、画面比率の違う端末で黒い部分にも絵が出せるようにしてみます。


例えば、サンプルの定義
def.h
static const int	SCREEN_WIDTH  = 640,					// 画面サイズ
					SCREEN_HEIGHT = 960;
static const int	LIMIT_WIDTH   = 640,					// 表示画面サイズ
					LIMIT_HEIGHT  = 1136;

この場合、アプリの内部での画面範囲は (-640/2, -1136/2) - (640/2, 1136/2)になりますが、640x960の端末では (-640/2, -960/2) - (640/2, 960/2)の範囲しか描画されません。
上下88ドットずつ、端末の画面サイズによって描画されたりされなかったりする部分となります。
640:960より横長の端末では、縦960ドット分が描画され左右に黒い帯ができます。

このように仕様を決めてしまえば、変更点は多くありません。

Renderer.h
	static SRect			screen_rect;				// 画面解像度
	static SRect			limit_rect;					// 表示画面解像度

クラス sys::Rendererに表示画面解像度を追加しています。

Renderer.cpp
	if ( width*SCREEN_HEIGHT < height*SCREEN_WIDTH ) {		// 横長(上下カット)
		screen_rect.w = width;
		screen_rect.h = width*SCREEN_HEIGHT/SCREEN_WIDTH;
		limit_rect.w  = width*LIMIT_WIDTH/SCREEN_WIDTH;
		limit_rect.h  = width*LIMIT_HEIGHT/SCREEN_WIDTH;
	}
	else {													// 縦長(左右カット)
		screen_rect.w = height*SCREEN_WIDTH/SCREEN_HEIGHT;
		screen_rect.h = height;
		limit_rect.w  = height*LIMIT_WIDTH/SCREEN_HEIGHT;
		limit_rect.h  = height*LIMIT_HEIGHT/SCREEN_HEIGHT;
	}
	screen_rect.x = (width - screen_rect.w)/2;
	screen_rect.y = (height - screen_rect.h)/2;
	limit_rect.x  = (width - limit_rect.w)/2;
	limit_rect.y  = (height - limit_rect.h)/2;

画面初期化部分です。
フレームバッファは表示画面の大きさ LIMIT_WIDTH、LIMIT_HEIGHTに合わせます。
画面の拡大率は今まで同様 SCREEN_WIDTH、SCREEN_HEIGHTで計算して、limit_rectをそこに合わせるようにします。

	// フレームバッファテクスチャ描画
	glBindFramebuffer(GL_FRAMEBUFFER, 0);
	glViewport(limit_rect.x, limit_rect.y, limit_rect.w, limit_rect.h);

描画部分です。
ビューポートを limit_rectで設定しています。
描画ではもう screen_rectの方は使用していないのですが、タッチパネルの座標変換で使用しているので screen_rect自体は残しています。


サンプルでは、今まで640x960だった背景を 640x1136のものに差し替えています。

はみ出すことも辞さない

上下の追加部分をわかりやすく模様にしています。


※ビー玉の画像は「かわいいフリー素材集 いらすとや」から使わせていただきました。どうもありがとうございます。

プロジェクト一式は、こちらです。

まんがホーム 1月号2013/12/05

黒い大家さん
部屋の電気が点いてなきゃ、そりゃ人が住んでるとは思われないでしょう。
電飾は材料費だけじゃなく電気代もかかりそうなんだが。

オトナのいろは
最終回っぽい雰囲気だけど、最終回じゃない。

ただいま独身中
最終回だけど、最終回っぽい雰囲気じゃない。

マチ姉さんの妄想アワー
なんぼ貧しいといっても、食事がわびし過ぎやしませんか?

半熟やおよろず
ゲストのまま最終回とは残念。
武将みたいに、日本の神とか仏のキャラクタ化が流行ったりしないかな。