<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns="http://purl.org/rss/1.0/"
 xmlns:content="http://purl.org/rss/1.0/modules/content/"
 xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
 xmlns:admin="http://webns.net/mvcb/"
 xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel rdf:about="http://blog.livedoor.jp/techblog/">
<title>livedoor Techブログ</title>
<link>http://blog.livedoor.jp/techblog/</link>
<description>ライブドアのエンジニア陣によるブログです。
大規模なサイト構築の裏側や気になる技術情報を掲載していきます。
</description>
<dc:language>ja</dc:language>
<admin:generatorAgent rdf:resource="http://blog.livedoor.com/?v=2.0" />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
<items>
 <rdf:Seq>
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/67283015.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/67207827.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/67023203.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66926680.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66795111.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66819913.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66785336.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66784747.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66780326.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66768375.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66736413.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66266188.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66595391.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66560080.html" />
  <rdf:li rdf:resource="http://blog.livedoor.jp/techblog/archives/66528186.html" />
 </rdf:Seq>
</items>
</channel>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/67283015.html">
<title>「livedoor × DeNA 勉強会」 #LDeNA を開催しました</title>
<link>http://blog.livedoor.jp/techblog/archives/67283015.html</link>
<description>こんにちは、１月から技術広報も兼任することになりました
NHN Japan ウェブサービス本部 開発２室の櫛井です。

株式会社ライブドアは１月よりNHN Japan 株式会社として新たに動き出しておりますが
まだライブドア時代に「お互いまだ近所にいるうちに勉強会しません？」とお...</description>
<dc:creator>kushii_</dc:creator>
<dc:date>2012-01-31T10:15:05+09:00</dc:date>
<dc:subject>お知らせ</dc:subject>
<content:encoded><![CDATA[こんにちは、１月から技術広報も兼任することになりました<br>
NHN Japan ウェブサービス本部 開発２室の櫛井です。<br>
<br>
株式会社ライブドアは１月より<a href="http://www.nhncorp.jp/" target="_blank">NHN Japan 株式会社</a>として新たに動き出しておりますが<br>
まだライブドア時代に「<b>お互いまだ近所にいるうちに勉強会しません？</b>」とお誘いして<br>
株式会社ディー・エヌ・エーの皆さんと合同勉強会を開催しました。その名も #LDeNA ！<br>
<br>
<br>
<img src="http://livedoor.blogimg.jp/techblog/imgs/4/1/41297738-s.jpg" width="500" height="332" border="0" alt="DSC09992" hspace="5" class="pict"  /></a><br>
<br>
<br>
トークは交代で20分程度の講演を行う形で、公開出来る範囲でいうと以下の内容で行いました。<br>
<br>
・DeNA @<a href="https://twitter.com/#!/nekokak" target="_blank">nekokak</a><br>
「Clutch - distributed job system」<br>
<br>
・NHN Japan @大型新人<br>
「microdata を活用しよう | JS に値を渡すときは data-* にしよう」<br>
<br>
・DeNA @隠し玉<br>
「みんなでパケットを取ろう」<br>
<br>
・NHN Japan @<a href="https://twitter.com/#!/tagomoris" target="_blank">tagomoris</a><br>
「ログ収集・集計基板をつくるときのいくつかの試行錯誤」<br>
<br>
<br>
<br>
この他、飛び入りも含めると４つの Lightning Talk があったり、その場限りの面白トークで<br>
大いに盛り上がりました。<br>
<br>
<br>
というところで、次回はおそらく弊社が渋谷ヒカリエに移転してからの開催となりそうです。<br>
「この勉強会参加したい！」という腕に覚えのある方、NHN Japanへのエントリーお待ちしております。<br>
<br>
<br>
<a href="http://www.nhncorp.jp/career/index.html" target="_blank">NHN Japan Corporation ｜ 採用情報</a><br>
<br>
<br>
こちらのブログも近いうちにNHN Japan仕様に変更予定です。
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=67283015" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/67207827.html">
<title>AndroidでマルチリンガルTTS(音声合成)アプリ</title>
<link>http://blog.livedoor.jp/techblog/archives/67207827.html</link>
<description>はじめましてこんにちは
9月に入社しました、Androidアプリ開発者のたかなです。

今日はAndroidの搭載機能である「TTS（音声合成）」を用いた
マルチリンガルTTSアプリを作ってみたいと思います!





TTSとは
TTSは Text To Speech の略です。読んで字のごとく、音声合成を...</description>
<dc:creator>techblog</dc:creator>
<dc:date>2012-01-05T12:00:45+09:00</dc:date>
<dc:subject>Android</dc:subject>
<content:encoded><![CDATA[はじめましてこんにちは<img src="http://parts.blog.livedoor.jp/img/emoji/1/ic_ribbon.gif" /><br>
9月に入社しました、Androidアプリ開発者のたかなです。<br>
<br>
今日はAndroidの搭載機能である「TTS（音声合成）」を用いた
マルチリンガルTTSアプリを作ってみたいと思います!<br>
<br>
<a href="http://livedoor.blogimg.jp/techblog/imgs/9/9/992bc1b1.png" title="20111228-171243" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/9/9/992bc1b1-s.png" width="320" height="569" border="0" alt="20111228-171243" hspace="5" class="pict"></a><br>
<br>
<br>
<br>
<h2>TTSとは</h2><br>
TTSは Text To Speech の略です。読んで字のごとく、<b>音声合成</b>を指します。<br>
<br>
初音ミクなどのVocaloid、駅のアナウンス、ロボットに搭載されている音声を耳にしたことがある人も多いでしょう。<a href="http://chi.usamimi.info/Program/Application/BouyomiChan/" target="_blank" title="">棒読みちゃん</a>を使っている人もいるかもしれませんね。<br>
<br>
TTSは「動的に変化する情報をリアルタイムにしゃべってほしい」「状況に応じて素早くアナウンスしたい」「いつでも、どこでも、手間をかけずに情報を発信したい」といったニーズに対応するよう作られ、郵便局や病院の番号札の読み上げなどから、近年では肉声に近いなめらかな発音のモデルも増えてきました。<br>
<br>
<br>
<h2>AndroidにTTSが標準搭載</h2><br>
Android 1.6から、TTS機能が標準搭載されています。<br>
ただし、<b>音声を合成するためにはボイスデータと呼ばれる音声のパーツの集合（アプリ形式）をインストールする必要があり、そのままでは使うことができません</b>。<br>
<br>
今回のアプリではその点を加味して、ボイスデータの有無をチェック、なければマーケットの該当アプリへ遷移する、という機能も付加しています。<br>
<br>
<br>
<h2>AndroidTTSの対応言語</h2><br>
現在、AndroidTTSの対応言語は「英語（イギリス英語を含む）」「フランス語」「ドイツ語」「イタリア語」「スペイン語」の5つです。
自分のAndroid端末がどの言語をしゃべれるかは、「設定」→「音声入出力」→「テキスト読み上げの設定」→「言語」で確認できます。<br>
<br>
残念ながら<b>日本語非対応</b>とのことで、日本語の合成を実現するためには別のライブラリが必要です。<br>
<br>
<br>
<h2>AndroidTTSを使ってみる</h2><br>
SDKの「TextToSpeech」クラスを使います。<br>
リファレンスはこちら　<a href="http://developer.android.com/intl/ja/reference/android/speech/tts/TextToSpeech.html" target="_blank" title="">TextToSpeech - Android Developers</a><br>
<br>
しゃべらせること自体はとても簡単で、
<b>speak</b>メソッドの引数に読んでほしいテキストを与えるだけです。<br>
各言語の設定を行うには<b>setLanguage</b>メソッドでLocaleを指定します。<br>
今の設定がどの言語か?を調べるためには<b>getLanguage()</b>しましょう。<br>
<br>
また、自分以外の人の端末でアプリを使って欲しい場合は、その端末の対応言語を調べる必要があります。<br>
これは<b>isLanguageAvailable</b>メソッドにLocaleを指定することで、ステータスがTextToSpeechの定数として返ってきます。<br>
<br>
例）端末がアメリカ英語のTTSに対応可能かを判断するためには<br>
<pre class="brush:java;gutter:false;">
if (mtts.isLanguageAvailable(Locale.US) >= TextToSpeech.LANG_AVAILABLE) {
　　　//対応可能だった時の処理
}
</pre><br>
となります。
TextToSpeech.LANG_AVAILABLEは「言語が使用可能である」ことを指していて、
ステータスがLANG_AVAILABLE以上の状態であれば合成が可能です。<br>
<br>
余談ですが、サポートされていないLocaleならLANG_NOT_SUPPORTED、必要なボイスデータがインストールされていないとLANG_MISSING_DATAが返ってくるので、必要に応じて処理を加えましょう。<br>
<br>
<br>
<h2>作ってみよう</h2><br>
アプリの仕様です。<br>
<br>
<ol><li>はじめにボイスデータがあるかどうかチェックする</li><br>
<li>ヘルプボタンを押すとガイド音声が流れる</li><br>
<li>デフォルトはアメリカ英語</li><br>
<li>テキストを入力して「TextToSpeech!」ボタンを押すと合成し再生</li><br>
<li>「Laguage」ボタンで言語の切り替えが可能</li></ol><br>
<br>
<br>
<h2>サンプルコード</h2><br>
TextToSpeechActivity.java<br>
<br>
<pre class="brush:java;gutter:false;">
package jp.android;

import java.util.Locale;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class TextToSpeechActivity extends Activity  implements TextToSpeech.OnInitListener {

    private static final int CHECK_TTS = 682730935;
    private Button mSpeakButton;
    private TextToSpeech mTts;
    private EditText et;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        this.checkTTS();

        mTts = new TextToSpeech(this, this);

        this.mSpeakButton =
            (Button) findViewById(R.id.speak_button);
        et = (EditText)findViewById(R.id.inputText);
        mSpeakButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startTTS(et.getText().toString());
            }
        });

    }

    /**
     * TTSエンジンがインストール済かどうかを判定
     */
    private void checkTTS() {
        Intent intent = new Intent();
        intent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
        startActivityForResult(intent, CHECK_TTS);        
    }

    // チェックの結果を受け取る
    protected void onActivityResult(int requestCode, int resultCode,
            Intent data) {
        if (requestCode == CHECK_TTS) {
            if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
                //インストール済ならウェルカムメッセージを発話
                startTTS("Welcome to TTS application, Let`s start!");
            }
            else {
                //インストール無しなら
                Intent install = new Intent();
                install.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
                startActivity(install);
            }
        }
    }

    /**
     * 合成を実行
     * @param text 読み上げたいテキスト
     */
    private void startTTS(String text) {
        mTts.speak(text, TextToSpeech.QUEUE_FLUSH, null);
    }

    /**
     * ヘルプガイドを読み上げる
     * @param v
     */
    public void startGuide(View v) {
        mTts.setLanguage(Locale.US);
        startTTS(getString(R.string.guide));
    }

    /**
     * 言語選択ボタン
     * @param v
     */
    public void onSelectLang(View v) {
        AlertDialog.Builder ab = new AlertDialog.Builder(this);
        String[] str = {"English","French","German","Italian","United Kingdom"};
        ab.setItems(str, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int i) {
                switch (i){
                    case 0:
                        mTts.setLanguage(Locale.US);
                        break;
                    case 1:
                        mTts.setLanguage(Locale.FRENCH);
                        break;
                    case 2:
                        mTts.setLanguage(Locale.GERMAN);
                        break;
                    case 3:
                        mTts.setLanguage(Locale.ITALIAN);
                        break;
                    case 4:
                        mTts.setLanguage(Locale.UK);
                            break;
                }
                
            }
        });
        ab.show();
    }

    public void onInit(int status) {        
        if (status == TextToSpeech.SUCCESS) {
            if (mTts.isLanguageAvailable(Locale.US) >= 
                    TextToSpeech.LANG_AVAILABLE) {
                //アメリカ英語に設定
                mTts.setLanguage(Locale.US);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        mTts.shutdown();
    }
}

</pre><br>
<br>
<a href="http://livedoor.blogimg.jp/techblog/imgs/2/3/2318d16f.png" title="20111228-171254" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/2/3/2318d16f-s.png" width="320" height="569" border="0" alt="20111228-171254" hspace="5" class="pict"/></a><br>
<br>
非常に簡単にマルチリンガルなTTSアプリが作れました。<br>
<br>
<br>
<h2>注意点</h2><br>
<b>speak</b>メソッドは非同期なので、音声の合成処理・再生中はタスクの状態に応じた処理が必要です。特に長い文章を読ませたい場合（入力される文字数を制限しない場合）は注意しましょう。<br>
<br>
<br>
<h2>サンプルプロジェクトのソース</h2><br>
スペースの関係で全部のソースは載せられないので、こちらに置いておきます。<br>
<a href="https://www.assembla.com/code/texttospeech/git/nodes" target="_blank" title="">https://www.assembla.com/code/texttospeech/git/nodes</a><br>
<br>
<br>
<h2>まとめ</h2><br>
AndroidTTSを使うと、手軽に音読アプリが作れます。<br>
合成から音声再生までのレスポンスが速いので、ちょっとした外国語のトレーニングに使えそうですね。<br>
定型文をあらかじめ入力しておけば、海外旅行にも役立ちそうです。<br>
<br>
また、今年1月から、全てのAndroid端末で　音声対話型コンシェルジュサービス<a href="http://www.netpeople-a.com/" target="_blank" title="">netpeople : a</a>が利用可能になるとのことなので、TTSが日本語サポートされたら<a href="http://www.youtube.com/watch?v=ItfDzLfpoi4" target="_blank" title="">端末同士の会話</a>が実現するかもしれません。<br>
<br>
<br>
<h2>＜おまけ＞Androidで使える日本語TTSライブラリ</h2><br>
日本語で音声合成してみたい!という方向けに公開されているライブラリです。<br>
有料のものがほとんどなので、気軽に試せないのが少し残念ですね。<br>
<br>
音声合成エンジン <a href="http://hil.t.u-tokyo.ac.jp/~galatea/index-jp.html" target="_blank" title="">"Galatea Talk"</a>を用いたライブラリ<br>
<ul><li><a href="http://gimite.net/pukiwiki/index.php?Android%20JaTTS" target="_blank" title="">Android JaTTS</a></li><br>
<br>
株式会社アクエストの音声合成ライブラリ。評価版あり。<br>
<li><a href="http://www.a-quest.com/products/aquestalk.html" target="_blank" title="">AquesTalk</a></li><br>
<br>
クリエートシステム開発株式会社の音声合成ライブラリ。Android用SDKになっています。<br>
<li><a href="http://www.createsystem.co.jp/dtalkerAndroidSDK.html" target="_blank" title="">ドキュメントトーカ日本語音声合成エンジン for Android</a></li><br>
<br>

HOYA株式会社の音声合成ライブラリ。中国語・韓国語に対応しているよう。<br>
<li><a href="http://voicetext.jp/use_smartphone.html" target="_blank" title="">VoiceText</a></li><br>
<br>
株式会社エーアイの音声合成ライブラリ<br>
<li><a href="http://www.ai-j.jp/micro" target="_blank" title="">micro AITalk</a></li></ul>
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=67207827" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/67023203.html">
<title>Titanium最前線</title>
<link>http://blog.livedoor.jp/techblog/archives/67023203.html</link>
<description>こんにちは！こんにちは！もしかしてこんばんは！
開発部のあぶいです。

今回は、Appcelerator社が提供しているTitanium Mobileについて最近の事情も踏まえてお話させていただきます。

Titanium MobileとはTitanium MobileとはJavascriptによってiOSもしくはAndroidのアプ...</description>
<dc:creator>abui</dc:creator>
<dc:date>2011-11-02T16:25:03+09:00</dc:date>
<dc:subject>Titanium</dc:subject>
<content:encoded><![CDATA[こんにちは！こんにちは！もしかしてこんばんは！<br>
開発部のあぶいです。<br>
<br>
今回は、Appcelerator社が提供しているTitanium Mobileについて最近の事情も踏まえてお話させていただきます。<br>
<br>
<h2>Titanium Mobileとは</h2>Titanium MobileとはJavascriptによってiOSもしくはAndroidのアプリを作ることができる開発環境のことです。触れ込みとしては一つのソースでiOS・Androidの両方で動かすことができるとありますが、実際は片方でしか使えないメソッドがあったりするので内部で分岐させながらクロスプラットフォーム対応させているのが現実のようです。<br>
<br>
よく比較される製品としてPhoneGapがありますが、見た目に関わる部分をHTML5+CSS3で作ることを前提にしているPhoneGapと比べてTitanium Mobileではレイアウト・ロジックを含め全てJavascriptで記述します。UI部品に関してもネイティブと同様のものを使うのでよりネイティブに近いアプリを作ることができる環境といえるでしょう。<br>
<br>
<br>
<br>
<h2>コスプレサイトCureの画像閲覧アプリ「Cure Viewer」 </h2>弊社でもいくつかアプリをリリースしていますが、今年(2011年)の9月初頭にリリースしたコスプレサイトCureの画像閲覧アプリはTitanium Mobileによって作られています(現在iPhone版のみです)。<br>
コスプレイヤーな人もそうでない人も使えるアプリなのでこの機会に是非ダウンロードしてみてください！<br>
<br>
<b>Cure Viewer</b> (Appstoreで「cure」と検索してください)<br>
<a href="http://itunes.apple.com/jp/app/cure-viewer/id460332254?mt=8" target="_blank">http://itunes.apple.com/jp/app/cure-viewer/id460332254?mt=8</a><br>
<br>
さて、このCure Viewerですが、私にとっては突然ふってきた案件でした。まったくアプリの開発経験がない私に<br>
<br>
<span style="font-size: 140%">「最近Titanium Mobileっていうのがあるじゃない。<br>
&nbsp;&nbsp;こういう案件があるんだけど、あぶい君Javascript得意だよね。じゃよろしく。」</span><br>
<br>
と確かこんな感じでふられた記憶があります。大分ざっくりいうとですが。<br>
<br>
そんなTitanium Mobile初心者が開発時に参考にしてたサイトは以下の二つです。<br>
<br>
<b>Titanium Mobileの公式APIドキュメント</b><br>
<a href="http://developer.appcelerator.com/apidoc/mobile/latest" target="_blank">http://developer.appcelerator.com/apidoc/mobile/latest</a><br>
※更新が遅れている為、たまにドキュメントにのってなくても使えるプロパティーがあるので要注意です。<br>
<br>
<b>KitchenSink</b><br>
<a href="https://github.com/appcelerator/KitchenSink" target="_blank">https://github.com/appcelerator/KitchenSink</a><br>
※Titanium Mobileのサンプル集。できるできないで困ったときはまずここをチェックする。<br>
<br>
どちらともメジャーではありますが、Javascriptについてある程度精通している場合はこの二つで充分間に合います。<br>
むしろAppstoreにあげるまでの手順の方が難しくて挫折しそうでした。<br>
<br>
<br>
<br>
<h2>Titanium Developerの行方</h2>Cure ViewerはEmacsとTitanium Developerで開発しました。<br>
<br>
Titaniumアプリの統合開発環境としてTitaniumStudioというものもありますが、エミュの立ち上げとアプリのビルドという必要最低限の機能しか有していないTitanium Developerの方がシンプルで使い勝手がよかったからです。<br>
このTitanium Developerですが現在ではAppcelerator社によるオフィシャルな開発はストップしています。実際githubにあがっているTitanium DeveloperのレポジトリにあるREADMEには以下のように記載されています。<br>
<br>
<a href="https://github.com/appcelerator/titanium_developer/blob/master/README" target="_blank">https://github.com/appcelerator/titanium_developer/blob/master/README</a><br>
<blockquote>Titanium Developer has been replaced by Titanium Studio. Although the source code remains open source, we will no longer be maintaining this code or releasing any new versions.</blockquote><br>
Appcelerator社としてはTitaniumStudioの方に全面移行したがっているようですね！<br>
<br>
しかしTitanium Developerの方も需要があるのか有志の人がTitanium Developerをforkして新しいバージョンとして開発しているようです。<br>
TiDEV Communityというそうです。<br>
<br>
<b>TiDEV Communityのスレッド</b><br>
<a href="http://developer.appcelerator.com/question/121270/titanium-developer-130" target="_blank">http://developer.appcelerator.com/question/121270/titanium-developer-130</a><br>
<br>
<b>TiDEV CommunityをDownload</b><br>
<a href="http://api.appcelerator.net/p/pages/app_page?token=m4rZLSv6" target="_blank">http://api.appcelerator.net/p/pages/app_page?token=m4rZLSv6</a><br>
<br>
TiDEV CommunityではTitanium Developerにはなかった「Launch with Full Compile」ボタンやビルドするSDKのバージョンを選択できたりと、さらにかゆいところに手が届くようになっているのでTitanium Developerを使っていた人におすすめです。<br>
<br>
さて、『アプリの開発』～『リリース』までをネイティブと同様にとどこおりなくできることは分かったとして、ではコミュニティの方はどうなのでしょうか。<br>
<br>
<br>
<br>
<h2>Titanium meetup Tokyo #14</h2><a href="http://livedoor.blogimg.jp/techblog/imgs/9/1/91e273cc.jpg" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/9/1/91e273cc-s.jpg" width="320" height="240" border="0" alt="28" hspace="5" class="pict"  /></a><br>
日本におけるTitaniumのコミュニティとして@masuidriveさんが定期的に主催されているTitanium Meetupが有名です。<br>
<br>
この集まり普段はもくもくとコードを書いたりゆるく喋ったりするいわゆるHackathon的な集まりなのですが、先日に開催されたTitanium meetup Tokyo #14ではAppceleratorのCEOであるJeff Haynie氏が来日して発表するということで、普段の雰囲気とは違い大分盛り上がっていました。<br>
<br>
JeffからはTitanium(会社、ソフトウェア、コミュニティ含め)の現在と未来のあり方についてと、11月に正式にリリースされるであろうTitanium SDK 1.8betaの具体的なアップデートの内容について発表がありました。<br>
<br>
発表の内容はUstreamのRecordedより見ることができます。<br>
<br>
<b>Titanium Meetup Tokyo #14 Vol.1</b><br>
Jeffによるプレゼンと質疑応答<br>
<object width="480" height="296" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param name="flashvars" value="vid=18138607&amp;autoplay=false&amp;locale=ja_JP"/><param name="allowfullscreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="src" value="http://www.ustream.tv/flash/viewer.swf"/><embed flashvars="vid=18138607&amp;autoplay=false&amp;locale=ja_JP" width="480" height="296" allowfullscreen="true" allowscriptaccess="always" src="http://www.ustream.tv/flash/viewer.swf" type="application/x-shockwave-flash"></embed></object><br>
<a href="http://www.ustream.tv/" style="padding: 2px 0px 4px; width: 400px; background: #ffffff; display: block; color: #000000; font-weight: normal; font-size: 10px; text-decoration: underline; text-align: center;" target="_blank">Video streaming by Ustream</a><br>
<br>
<b>Titanium Meetup Tokyo #14 Vol.2</b><br>
日本のTitaniumerがTitanium Mobileで開発したアプリをプレゼン<br>
<object width="480" height="296" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"><param name="flashvars" value="vid=18139519&amp;autoplay=false&amp;locale=ja_JP"/><param name="allowfullscreen" value="true"/><param name="allowscriptaccess" value="always"/><param name="src" value="http://www.ustream.tv/flash/viewer.swf"/><embed flashvars="vid=18139519&amp;autoplay=false&amp;locale=ja_JP" width="480" height="296" allowfullscreen="true" allowscriptaccess="always" src="http://www.ustream.tv/flash/viewer.swf" type="application/x-shockwave-flash"></embed></object><br>
<a href="http://www.ustream.tv/" style="padding: 2px 0px 4px; width: 400px; background: #ffffff; display: block; color: #000000; font-weight: normal; font-size: 10px; text-decoration: underline; text-align: center;" target="_blank">Video streaming by Ustream</a><br>
<br>
<br>
<br>
<h2>Titanium Mobile SDK 1.8.0について</h2>私たち開発者にとってもっとも関係のあるSDK 1.8betaの公式リリースですが、Jeffの発表があった翌日に公式ブログにてSDK1.8についてのさらに技術的な詳細が発表されました。<br>
<br>
<a href="http://developer.appcelerator.com/blog/2011/10/platform-engineering-sneak-peek-at-1-8-0.html" target="_blank">http://developer.appcelerator.com/blog/2011/10/platform-engineering-sneak-peek-at-1-8-0.html</a><br>
<br>
内容を要約してリストアップすると以下のようです。<br>
<br>
<ul><li>1.8.0からはtiapp.xmlに設定をすることによりAndroidのJavascript RuntimeをRhinoからV8へと変更することができる(まだいくつか大きな不具合が残っているが、年末までにはいいものをリリースすることができる)<br>
<li>Rhinoと比較するとV8の方がJSONのパース、TableViewへのRowのインサート、TableViewのスクロール、アプリケーションの立ち上げにおいてよりいいパフォーマンスがでている<br>
<li>View(Ti.UI.Viewなど)にconvertPointToViewという指定したView(Ti.UI.Windowなど)からの相対的な位置を取得するメソッドを追加する(<a href="https://github.com/appcelerator/titanium_mobile/blob/master/demos/KitchenSink/Resources/examples/view_point_conversion.js#L87" target="_blank">参考</a>)<br>
<li>TableViewのappendRowの引数に配列を受け取れることができるようになる<br>
<li>[Android] スクリーンの自動OFFを止められるようになる<br>
<li>[iOS, Android] longpressというイベントを追加<br>
<li>[iOS] ScrollViewにdragStartとdragEndというイベントを追加<br>
<li>[iOS] Ti.Media.takeScreenshotからとれるスクリーンショットのサイズがRetinaディスプレイの場合640x960になる<br>
<li>[iOS] HXRから取得するコンテンツにディスクキャッシュを用いれるようになる<br>
<li>長らく更新していなかったAPI Documentationが新しくなる<br>
<li>MobileWebを作るためのSDKのbetaバージョンも同時にバンドルされる</ul>2011/11/02現在、公式にはリリースされていませんが、手動でSDKの1.8betaをいれることができます。<ol><br>
<li><a href="http://builds.appcelerator.com.s3.amazonaws.com/index.html" target="_blank">http://builds.appcelerator.com.s3.amazonaws.com/index.html</a>へアクセス<br>
<li>branch: 1_7_Xとなっているプルダウンをmasterに切り替える<br>
<li>OSX, Linux, Windowsそれぞれ必要なリンクをコピー<br>
<li>TitaniumStudioの「Help」->「Install Titanium SDK from URL」へペーストしてインストール [OR] ローカルにダウンロードして該当のフォルダへ解凍してコピー(Macの場合/Library/Application Support/Titanium/mobilesdk/osx/)</ol>SDK1.8対応済みの<a href="https://github.com/appcelerator/titanium_mobile" target="_blank">KitchenSinkは公式のTitaniumMobileのレポジトリ</a>をローカルに落とした後の/demos/KitchenSink/にあります<br>
<br>
実際に1.8SDK betaでコンパイルしたKitchenSinkを手持ちのiPhone3GS+iOS5にいれてみましたが、Ti.UI.tableViewにRowを2000回インサートしたときのパフォーマンスが1000ms(3100ms->2100ms)ほど短くなっていました(比較したのはSDK1.7.1でコンパイルしたものです)。<br>
<br>
より詳細なパフォーマンスチェックをするには時間が必要ですが、確実にパフォーマンスは上がっているようなので正式なリリースが楽しみですね。<br>
<br>
<br>
<br>
<h2>終わりに</h2>Javascriptによってアプリを開発するというTitanium Mobileのアプローチは既存のWeb開発者が馴染みのある言語で開発をはじめることができるという点で学習コストを抑えることができ、そして開発スピードを向上できるという利点があります。<br>
また、本業ではない方が実際に動かせるアプリのプロトタイプを手軽に素早く作れるという点でも有用であると思います。<br>
<br>
これからの日本におけるTitaniumの発展はまず第一にTitanium自体の高速化と機能の充実が必要なのはいうまでもありませんが、コミュニティの発展とりわけTitanium開発者個々人のアウトプットが重要になると思います。<br>
その意味で先日行われたTitanium Meetup Tokyo #14は日本におけるTitanium発展のターニングポイントの一つであると感じました。<br>
<br>
次回は技術寄りのディープな話題を提供できればと思います。それでは！<br>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=67023203" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66926680.html">
<title>Facebook f8に参加してきました！</title>
<link>http://blog.livedoor.jp/techblog/archives/66926680.html</link>
<description>こんにちは、いつも年相応に見てもらえないOklahomerです。9/12-14のTechCrunch Disruptと9/22のFacebook f8に参加してきましたのでその報告と共有です。TechCrunch Disruptの詳細についてはディレクターブログにまとめられているのでそちらを参考にしていただくとして、ここ...</description>
<dc:creator>oklahomer</dc:creator>
<dc:date>2011-10-06T19:00:49+09:00</dc:date>
<dc:subject></dc:subject>
<content:encoded><![CDATA[こんにちは、いつも年相応に見てもらえない<a href="http://www.facebook.com/Oklahomer" target="_blank">Oklahomer</a>です。<br /><br />9/12-14の<a href="http://disrupt.techcrunch.com/SF2011/" target="_blank">TechCrunch Disrupt</a>と9/22の<a href="https://f8.facebook.com/" target="_blank">Facebook f8</a>に参加してきましたのでその報告と共有です。TechCrunch Disruptの詳細については<a href="http://blog.livedoor.jp/ld_directors/archives/51702489.html" target="_blank">ディレクターブログ</a>にまとめられているのでそちらを参考にしていただくとして、ここでは、両カンファレンスの参加者と交流してみた感想と、f8で発表された新機能の意義について共有したいと思います。<br /><br />また、f8で発表された新しいOpen Graphの実装などに関しては別エントリで共有したいと考えています。<br /><br /><br>
<h3>日本から参加する意義</h3><br>
今回参加した両カンファレンスではアフターパーティがあり、そこで交流を図る機会がありました。それに参加してみて思ったのは、当然ではありますが、本当に世界中あちこちから人が集まっているということです。たとえば、ロシアから来たと言う広告業界の人、ドイツやイギリスの投資家、イスラエルのエンジニア、コロンビアや台湾出身でシリコンバレーに住んでいる人々です。<br /><br />おそらく、これからシリコンバレーに進出する日本勢からすると、日本対シリコンバレーと言う構図で考えてしまい、「アメリカに行くんだから英語ちゃんとしなきゃ、英語まだまだできないから自分から声かけられない…」という考えになってしまうことは多いと思います。が、実際には色々な国から人が来ていて、それぞれが多かれ少なかれ言語の壁を乗り越えつつ、お互いのアイディアや技術を共有して何かを得ようとしている雰囲気でした。<br /><br />ですので、いきなり海外に行って現地のコミュニティに飛び込むというのは大きな壁を感じますが、新しい人と会って新しいアイディアを得たい人が相手ですから、こちらから何か与えられるものがあれば耳を傾けて歓迎してくれるというのが私の持った印象です。<br /><br />実際、Facebook f8前日の非公式パーティに参加して話した人たちは、日本の「ゆれくるコール」や「プリクラ」の話をすると、とても興味を持って聞いてくれました。地震の予知アプリというのは地震大国ならではのものですし、複数の画像でフォトモンタージュを作って落書きするアプリについて話していた彼らには、日本の女子高生文化にプリクラが定着しているというのが新鮮だったようです。まだまだ地震の予知から地震発生まで時間的な余裕がなくて…という話をした時に、「それをテクノロジーで変えられれば、世界はもっと良くなるね」と、サラッと言われたのが印象に残っています。<br /><br />両カンファレンスともリアルタイムで動画が配信されるなど、現地で参加しなくてもカンファレンス内容自体は追えてしまうので、「<span style="color: rgb(255, 0, 0);">いかに現地で参加者同士の交流を図れるか</span>」という点が、参加の意義に関わってくる気がしました。<br /><br>
<h3>Facebook新機能の意義</h3><br>
ここからはf8での発表に関してですが、発表内容については既にあちこちでまとめられていますので、このf8で発表された新機能（と直前に発表された「ニュースフィード/リアルタイムフィード/購読」）の意義について感じたことを書いて行きたいと思います。あくまで個人的に感じたことです。<br /><br>
<h4>全体</h4><br>
今回の「ニュースフィード/購読/リアルタイムフィード/タイムライン」の発表は、Facebookが目標としている、「to make the world more open and connected（世界をよりオープンでつながった状態にする）」を達成するにつれ増えて行く情報を整理するための、大きなステップだと感じています。そして新しいOpen Graphは、世界をよりオープンで繋がった状態にするためのステップです。<br>
<br>
<h5>増え続ける友達、溢れるニュースフィード</h5><br>
まず前提として、Robin Dunbarの「人間同士が良好な関係、安定した関係を築けるのは150人が限界」という説があります。これは時代や文化の関係なく、人間の能力としての限界のようです。Facebookが成長するに従い、増え続ける友達関係をどう維持するのかという話があちこちで取り上げられています。見つけられた限りで言うと、一番古いものは2008年の「<a href="http://www.newscientist.com/blog/technology/2008/04/is-150-friends-human-limit.html" target="_blank">Is 150 friends the human limit?</a>」という記事でした。この150という数値に対し、今現在のFacebookの<a href="http://www.facebook.com/press/info.php?statistics" target="_blank">公式発表</a>ではユーザ一人当たりの友達数は130人とされています。最近のブームで登録した新しいユーザ層の友達が少なく、平均を下げているとしたら、古くからのユーザは相当な量の友達数を持っているかと思います。<br /><br />当然、友達数が多ければニュースフィードに流れる情報量が増え、見たい情報は埋もれて行きますので、Facebookはエッジランクを用いるなどして対応してきました。しかし新しいOpen Graphの登場によって、今まで以上の情報がライフログとしてタイムラインに蓄積され、友達のニュースフィードにも流れて行きます。旅行などで数日間アクセスしない状況が続けば、これまでエッジランクを元に生成されていた「ハイライト」でも不十分となります。そこで、今度のニュースフィードには最終アクセス日時も考慮にいれ、不在だった期間の主立った出来事も要約して表示するようになりました。<br /><br />もう一つ、ニュースフィードに流される情報を整理する仕組みとして購読があります。Google+やTwitterへの追従として、一方的に人をフォローできるようになったという側面もありますが、この機能は既に友達関係にある人に対しても適用されます。この友達の写真投稿に関してはニュースフィードに流して欲しくないけど、ステータス投稿は流して欲しいなどの取捨選択が今まで以上に簡単にできるようになっています。<br>
<br>
<h5>よりオープンに</h5><br>
こうして、ユーザが見たがっていると思われる情報を抽出する仕組みは出来てきましたが、さらに世界をオープンにする仕掛けとしてリアルタイムフィードがあります。自分、友達Aさん、他人Bさんという3人がいたとして、AさんがBさんの公開ポストに対してコメントやいいね！をしても、それを自分が知るにはAさんのプロフィール画面に行く必要がありました。リアルタイムフィードの登場により、それがホームに居ながらにして分かります。また、ニュースフィードには流されないような小さな情報でも、ここにリアルタイムで流されて行きます。<br /><br />そして今回の目玉であるタイムラインです。ここには新しいOpen Graphによって追加される情報や、これまでFacebook上で行ってきた行動などが蓄積され、重要と思われるものを中心にサマライズされてライフログを形成します。Open Graphを利用したアプリによって、読んだニュース記事、走った距離、作った料理などがどんどん追加され、今までのプロフィール以上にユーザの性格が伝わるものへとなって行くはずです。<br>
<br>
<h5>まとめ</h5><br>
という具合に、「世界をよりオープンでつながった状態にする」というFacebookの目標に対して、一つ一つの機能の追加/更新が貢献する形になっているというのが、私から見た感想です。Open Graphとリアルタイムフィードに関しては、何でもかんでも情報が追加され流されてしまって気持ち悪くはありますが、すでにOpen Graphを用いているサービスでの解決策を示しつつ、次回はアプリケーション登録から実装までの流れを紹介したいと思います。<br>
<br />Facebookの情報に関しては「<a href="http://facebook-docs.oklahome.net/" target="_blank">Facebook開発者向けドキュメントの日本語訳とTips</a>」や<a href="http://www.facebook.com/Oklahomer" target="_blank">Facebookページ</a>でも紹介していますので、そちらも是非参照してください。
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66926680" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66795111.html">
<title>出来る Windows Phone アプリ開発</title>
<link>http://blog.livedoor.jp/techblog/archives/66795111.html</link>
<description>こんにちは!こんにちは!
開発部のやましーです。

今回は Windows Phone のアプリ開発-社内テスト-マーケットプレースへの提出の流れを簡単に紹介します。



Windows Phone 7.5 - Mango とは
Windows Phone 7.5 とはMicrosoft社製のスマートフォン用 OS が搭載され...</description>
<dc:creator>yamashitatakuya</dc:creator>
<dc:date>2011-09-29T10:00:48+09:00</dc:date>
<dc:subject>開発</dc:subject>
<content:encoded><![CDATA[こんにちは!こんにちは!<br />
開発部のやましーです。<br />
<br />
今回は Windows Phone の<span style="font-size: large; color:#00C0FF">アプリ開発</span>-<span style="font-size: large; color:#00C0FF">社内テスト</span>-<span style="font-size: large; color:#00C0FF">マーケットプレースへの提出</span>の流れを簡単に紹介します。<br />
<br />
<br />
<br />
<h3>Windows Phone 7.5 - Mango とは</h3>
<a href="http://mango.microsoft.com/windowsphone/ja-JP/" target="_blank">Windows Phone 7.5</a> とはMicrosoft社製のスマートフォン用 OS が搭載されたスマートフォン端末です。既に英語圏の国では Windows Phone 7.0 が発売済みでしたが、Windows Phone 7.5 で日本語を含むアジア言語がサポートされ、日本でも2011年8月25日に<span style="color: #EEEEEE;">ひっそりと</span>発売となりました。<br />
<br />
Windows Phone 7.5 の開発コードネームは <a href="http://mango.microsoft.com/windowsphone/ja-JP/" target="_blank"><span style="font-size: large; color:#FF8040">Mango</span></a>（マンゴー）と呼ばれているため、Windows Phone 系の情報サイトでは「Windows Phone Mango がリリース」や「Mango 端末」などと表現されることがあります。<br />
<br />
Mango<br />
<img src="http://livedoor.blogimg.jp/techblog/imgs/9/7/9796b307-s.jpg" width="160" height="120" border="0" alt="mango" hspace="5" class="pict"  /><br />
<br />
日本では2011年8月25日にフライング気味に発売されたようですが、実際のリリースは2011年の秋（9月末頃？）とのことです。<br />
<br />
<a href="http://mango.microsoft.com/windowsphone/ja-JP/" target="_blank">Windows Phone Mango 紹介サイト</a><br />
<br />
<br />
<br />
<h3><a name="requirement">アプリの開発に必要なもの</a></h3>
以下を準備することでアプリを開発してマーケットプレースへ提出できます。<br />
<br />
<h4>アプリの開発に必要なもの</h4>
<ul>
<li>Windows Phone 7.1 SDK (<a href="http://create.msdn.com/ja-JP/" target="_blank"><span style="font-weight: bold">ダウンロードはApp Hubから</span></a>)</li>
</ul>Windows Phone 7.1 SDK には下記の内容が含まれています。
<ul>
<li>Visual Studio 2010 Express for Windows Phone (C#/VB.NETでコードを書いてビルドする統合IDE)</li>
<li>Expression Blend 4 (ページデザインツール、必須ではないが使うと便利)</li>
<li>XNA Game Studio 4.0 Refresh (ゲーム開発用)</li>
<li>Windows Phone Emulator (エミュレーター)</li>
<li>Windows Phone Developer Registration (実機を開発者アンロックするツール)</li>
<li>Application Deployment (個別デプロイツール、普段は使わない)</li>
</ul>
Windows Phone 7.1 SDK のみで<span style="font-size: large; color:#00C0FF">アプリの開発</span>と<span style="font-size: large; color:#00C0FF">エミュレーター上での動作確認</span>まで可能です。<br />
<span style="color: #FF0000;">※ 実機で動作確認をするためには下記が必要です。</span><br />
<br />
<h4>実機で動作確認をするために必要なもの</h4>
<ul>
<li>App Hub メンバーシップ (年間 9,800円、<a href="http://create.msdn.com/ja-JP/" target="_blank"><span style="font-weight: bold">App Hubはこちら</span></a>)</li>
<li>Zune ソフトウェア（実機にデプロイするために必要、<a href="http://www.zune.net/ja-JP/" target="_blank"><span style="font-weight: bold">Zuneはこちら</span></a>）</li>
</ul>
<span style="font-size: large; color:#00C0FF">App Hub メンバーシップに加入</span>して実機を<span style="font-size: large; color:#00C0FF">開発者アンロック</span>状態にすることで、ビルドしたアプリを<span style="font-size: large; color:#00C0FF">実機へデプロイ</span>してのデバッグが可能になります。<br />
※ App Hub メンバーシップではなく <a href="http://labs.chevronwp7.com/" target="_blank">ChevronWP7</a> というサイトで開発者アンロック権を購入するような手段も準備されているようですが、まだ開始していないようです。<br />
<br />
<h5>開発者アンロック</h5>
App Hub メンバーシップ登録を終えた後に、Zune ソフトウェアを起動して、開発者アンロックをしたい端末を接続して、端末の画面ロックを解除した状態で、Windows Phone SDK 7.1 に付属の Windows Phone Developer Registration を起動して、App Hub のログインに使う Windows Live ID とパスワードを入力して「登録」ボタンをクリックすると、その端末は開発者アンロック状態になります。<br />
<br />
<h4>マーケットプレースへの提出に必要なもの</h4>
<ul>
<li>App Hub メンバーシップ （年間 9800円、<a href="http://create.msdn.com/ja-JP/" target="_blank"><span style="font-weight: bold">App Hubはこちら</span></a>）</li>
</ul>
App Hub のアカウント作成（登録）やメンバーシップの購入方法などは App Hub の下記のページに詳しく載っています。<br />
<br />
<a href="http://create.msdn.com/ja-jp/home/about/walkthrough/" target="_blank">App Hub - アプリケーションの配布および販売に必要な手続きについて</a><br />
<br />
<br />
<br />
<h3><a name="development">アプリの開発</a></h3>
今回は簡単なテストアプリを作ります。<br />
内容は twitter の ld_tech ユーザーのツイートをリスト表示するだけです（細かいことは次回）。<br />
<br />
<h4>新規プロジェクトの作成</h4>
新規プロジェクトを作成します。<br />
<br />
<ol>
<li>Visual Studio 2010 を起動（スタートメニュー→すべてのプログラム→Microsoft Visual Studio 2010 Express→Microsoft Visual Studio 2010 Express for Windows Phone）</li>
<li>メニューのファイル→新規作成→プロジェクトを選択する</li>
<li>「新しいプロジェクト」ダイアログが表示される</li>
<li>左上の「インストールされたテンプレート」で「Visual C#」を選択する</li>
<li>中央の「Windows Phone アプリケーション Visual C#」を選択（通常はデフォルトで選択されています）</li>
<li>下の「名前」を PhoneApp1 から適当な名前に変更してOKを押す（今回はテストアプリなので PhoneApp1 のまま作成）</li>
<li>「新しい Windows Phone アプリケーション」ダイアログが表示される</li>
<li>「対象の Windows Phone OS のバージョン」を選択してOKを押す（通常はそのまま Windows Phone OS 7.1 で作成）</li>
</ol>
これで新規プロジェクトの作成が完成しました。<br />
画面の左側にアプリのデザインプレビュー、中央にxaml（ザムル）、右側にソリューション エクスプローラーが表示されています。<br />
<br />
<h4>アプリタイトル・ページタイトルの変更</h4>
アプリとページのタイトルを変更します。<br />
<br />
<ol>
<li>画面右下に「プロパティ」ウィンドウが表示されていなければメニューの表示→プロパティ ウィンドウで表示</li>
<li>デザインプレビュー上の「マイ アプリケーション」をクリック</li>
<li>プロパティの「Text」を「livedoor Techブログ」に変更（xaml内のテキストを直接変更する方法もあります）</li>
<li>デザインプレビュー上の「ページ名」をクリック</li>
<li>プロパティの「Text」を「一覧」に変更</li>
</ol>
これでアプリとページのタイトルの変更が完了しました。<br />
<br />
<h4>ツイートの取得</h4>
アプリが起動したら twitter の検索APIを使って ld_tech ユーザーのツイートを取得する処理を書きます。<br />
ウェブサービスからRSS/Atomフィードを取得する処理は様々な方法で書けますが、今回のように<span style="font-size: large; color:#00C0FF">お手軽に実装</span>する場合は <a href="http://blogs.msdn.com/b/aonishi/" target="_blank">大西 彰のお仕事でのブログ </a> の <a href="http://blogs.msdn.com/b/aonishi/archive/2011/07/01/10181976.aspx" target="_blank">Windows Phone “Mango”: 短いコードでRSS/Atomフィードを一覧表示する方法</a> ページが参考になります（<span style="font-size: large; color: #FF0000;">※ ただしRSS 2.0 / Atom 1.0に限る</span>）。<br />
<br />
<h5>Syndication アセンブリを追加</h5>
RSSフィードを取得するのに使う Syndication というアセンブリを追加します。<br />
<br />
<ol>
<li>メニューのプロジェクト→参照の追加</li>
<li>「参照の追加」ダイアログが表示される</li>
<li>「参照」タブに移動する</li>
<li>C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries\Client の　System.ServiceModel.Syndication.dll を選択してOKを押す<br />（64ビットOSの場合は C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client）</li>
<li>「Windows Phone XNA アセンブリには、安全に…」という警告が表示されるが「はい」を押す</li>
</ol>
<br />
<h5>RSSフィードを取得するコードを書く</h5>
アプリが起動したらRSSフィードを取得するコードを書きます。<br />
<br />
<ol>
<li>ソリューション エクスプローラーの MainPage.xaml の下の階層にある MainPage.xaml.cs ファイルをダブルクリックして開く</li>
<li>コードの最初にある using 群の下に下記を追加<br />
<script type="syntaxhighlighter" class="brush: csharp">
<![CDATA[
using System.ServiceModel.Syndication; 
using System.IO; 
using System.Text; 
using System.Xml;
]] >
</script>
</li>
<li>コンストラクターの InitializeComponent(); の下に下記を追加。ただし cli.DownloadStringCompleted += の行は手入力して += の入力後にタブキーを2回押してメソッドの自動生成を行う。最後に忘れずに cli.DownloadStringAsync(uri); を入力。<br />
<script type="syntaxhighlighter" class="brush: csharp; highlight: [4,5,6,7]">
<![CDATA[
public MainPage()
{
    InitializeComponent();
    WebClient cli = new WebClient();
    Uri uri = new Uri("http://search.twitter.com/search.atom?q=ld_tech", UriKind.Absolute);
    cli.DownloadStringCompleted += new DownloadStringCompletedEventHandler(cli_DownloadStringCompleted); 
    cli.DownloadStringAsync(uri); 
}
]] >
</script>
</li>
<li>自動生成された cli_DownloadStringCompleted メソッド内の throw 処理を削除して下記を追加<br />
<script type="syntaxhighlighter" class="brush: csharp; highlight: [3,4,5,6]">
<![CDATA[
void cli_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    StringReader sr = new StringReader(e.Result); 
    XmlReader xr = XmlReader.Create(sr); 
    SyndicationFeed sf = SyndicationFeed.Load(xr); 
    this.DataContext = sf;
}
]] >
</script>
</li>
</ol>
コードの入力は以上です。<br />
<br />
ここで動作確認をしてみます。<br />
F5 キーを押すとビルド、エミュレーターの起動（起動していなければ）、デプロイ、デバッグ開始となります。<br />
<br />
実行結果<br />
<a href="http://livedoor.blogimg.jp/techblog/imgs/7/d/7d4b56fa.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/7/d/7d4b56fa-s.png" width="160" height="266" border="0" alt="app-capture-001" hspace="5" class="pict"  /></a><br />
<br />
アプリとページのタイトルのみ表示されれば正常です。エミュレーターの左下の「戻る」（矢印）ボタンでデバッグを終了します。<br />
<br />
次はアプリのデザインをやります。<br />
<br />
<br />
<br />
<h3><a name="design">アプリのデザイン</a></h3>
アプリのデザインは Visual Studio でも出来ますが、今回は<span style="font-size: large; color:#00C0FF">お手軽にデザイン</span>するために、Microsoft Expression Blend を使います。<br />
<br />
<h4>Microsoft Expression Blend</h4>
Microsoft Expression Blend は xaml ファイルをビジュアルデザインするツールです。<br />
今回は取得したRSSフィードの中身をリスト表示するデザインです。<br />
<br />
<h5>アプリにリストを追加</h5>
アプリのメインとなるリストを追加します。<br />
<br />
<ol>
<li>Blend を起動する（Visual Studio のメニュー→プロジェクト→Expression Blend を開く）</li>
<li>Blend 画面の右上にある「データ」タブを開く</li>
<li>「プロジェクト」と「このドキュメント」がリスト表示される</li>
<li>その右上にあるアイコン <img src="http://livedoor.blogimg.jp/techblog/imgs/4/6/466d110b.png" width="28" height="23" border="0" alt="create-sample-data-icon" hspace="5" class="pict" /> をクリックする</li>
<li>「クラスからのサンプル データの作成」を選択する</li>
<li>「クラスからのサンプル データの作成」ダイアログが表示される</li>
<li>一番下にある「すべてのアセンブリを表示する」をチェックする</li>
<li>「クラスの選択」リスト内の System.ServiceModel.Syndication を展開、その中の SyndicationFeed を選択、OKボタンを押す</li>
<li>「プロジェクト」に「SyndicationFeedSampleData」が追加される</li>
<li>「SyndicationFeedSampleData」の SyndicationFeed を展開する</li>
<li>続いて Items、Title を展開する</li>
<li>Title の中の Text : (String) をアプリ画面のメインエリアにドラッグ＆ドロップする</li>
<li>意味不明なアルファベットの羅列のオブジェクトが配置される</li>
<li>そのオブジェクトを右クリックして自動サイズ設定→ページ幅に合わせるを選択する</li>
<li>そのオブジェクトがアプリのメインエリア全体に広がる</li>
<li>そのオブジェクトがアプリのメインとなるリストです</li>
<li>意味不明なアルファベットの羅列はRSSフィードのタイトル項目のダミー値です</li>
</ol>
現時点ではこんな感じです。<br />
<a href="http://livedoor.blogimg.jp/techblog/imgs/2/9/29594047.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/2/9/29594047-s.png" width="160" height="266" border="0" alt="design-capture-001" hspace="5" class="pict"  /></a><br />
<br />
<h5>リスト内にもう１つ項目を追加</h5>
追加されたリストにはすでにタイトル項目がありますが、更にテキスト項目を追加します。<br />
<br />
<ol>
<li>Blend 画面の左下にある「オブジェクトとタイムライン」ウィンドウで一番下の ListBox が選択されていることを確認する</li>
<li>選択されていなければ選択する</li>
<li>メニューのオブジェクト→追加テンプレートの編集→生成されたアイテム の編集→現在のテンプレートの編集を選択する</li>
<li>「オブジェクトとタイムライン」内のリストがリスト内のデザイン用に切り替わる</li>
<li>TextBlock をクリックして選択する</li>
<li>もう一度クリックすると名前を編集できるようになるので名前を Title に変更する</li>
<li>これがRSSフィードのタイトル項目です</li>
<li>続いて Blend 画面の一番左のアイコン <img src="http://livedoor.blogimg.jp/techblog/imgs/8/c/8c01c76f.png" width="32" height="31" border="0" alt="text-block-icon" hspace="5" class="pict"  /> をダブルクリックする</li>
<li>TextBlock が1つ追加される</li>
<li>追加された TextBlock をクリックして名前を Summary に変更する</li>
<li>右上の「データ」タブの SyndicationFeed から Summary の中の Text : (String) を、先ほど名前を付けた Summary の上にドラッグ＆ドロップする</li>
<li>これがRSSフィードのテキスト項目です</li>
</ol>
<br />
<h5>リストの整形</h5>
リスト内の項目の整形をします。<br />
<br />
<ol>
<li>「データ」タブが開かれているところの左にある「プロパティ」タブをクリックする</li>
<li>「オブジェクトとタイムライン」内の StackPanel を右クリックする</li>
<li>グループ化設定→Borderを選択する</li>
<li>追加された Border を全て展開する</li>
<li>Border、StackPanel、Title、Summary の4つのオブジェクトがあることを確認する</li>
<li>Border をクリックして選択する</li>
<li>プロパティの「概観」内にある Background が No brush になっているのを確認する</li>
<li>No brush の右にある小さい四角をクリックする</li>
<li>システム リソース→PhoneAccentBrushを選択する</li>
<li>項目の一部が水色に変わる</li>
<li>次に角を丸くするためにプロパティの「概観」内にある CornerRadius を 10 にする</li>
<li>角が丸くなる</li>
<li>プロパティの「レイアウト」内にある Margin の上下をそれぞれ 5 に変更する</li>
<li>リストアイテムの上下に隙間が空く</li>
<li>同じく Padding の上下左右を 10 に変更する</li>
<li>リストアイテム内に余白ができる</li>
<li>「オブジェクトとタイムライン」内の StackPanel を選択する</li>
<li>プロパティの「レイアウト」内の Width を 450 に変更する</li>
<li>続いて高さを自動調整するために Height の数値の右にある全画面表示のようなアイコンをクリックする</li>
</ol>
だいたいこんな感じで。<br />
<a href="http://livedoor.blogimg.jp/techblog/imgs/3/6/3694fbd8.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/3/6/3694fbd8-s.png" width="160" height="266" border="0" alt="design-capture-002" hspace="5" class="pict"  /></a><br />
<br />
ためしに F5 キーを押して実行してみます。<br />
<br />
実行結果<br />
<a href="http://livedoor.blogimg.jp/techblog/imgs/3/0/30d7dfee.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/3/0/30d7dfee-s.png" width="160" height="266" border="0" alt="design-capture-003" hspace="5" class="pict"  /></a><br />
<br />
あれ、なぜか完成していますね。<br />
細かいレイアウトはその他のプロパティの値を調整することで、デザイン画面を見ながら調整できます。<br />
<br />
デザインが終わったので Blend を閉じて Visual Studio に戻ります。<br />
<br />
次はマーケットプレースへの提出をやります。<br />
<br />
<br />
<br />
<h3><a name="marketplace">マーケットプレースへの提出（社内テスト用）</a></h3>
マーケットプレースへの提出には配布対象が2種類あって、ひとつは <span style="font-size: large; color:#00C0FF">パブリック Marketplace</span>、もうひとつは <span style="font-size: large; color:#00C0FF">プライベート ベータテスト</span> です。後者のプライベート ベータテストは iOS アプリのベータ版を配布するときに便利な <span style="font-size: large; color:#00C0FF">TestFlight のようなもの</span> です。今回は社内テスト向けなのでプライベート ベータテスト向けに配布します。<br />
<br />
<h4>マーケットプレースへの提出の際に必要なもの</h4>
マーケットプレースへ提出する際に下記のものが必要となるので準備しましょう。<br />
<br />
<ul>
<li>アプリのアイコン画像3種類（99x99、173x173、200x200）</li>
<li>スクリーンショット（480x800、最低1枚必要）</li>
<li>マーケットプレース背景画像（1000x800、オプション）</li>
</ul>
アイコン画像は自分で作るとして、<span style="font-size: large; color:#00C0FF">スクリーンショットはエミュレーターの右上にあるツールで撮る</span>ことができます。デバッグ実行状態だと実行画面の右側にパフォーマンス値が表示されてしまうので、エミュレーター上でホームボタンを押してスタート画面に戻り、左にフリックしてアプリ一覧からアプリを起動すると、パフォーマンス値が表示されない状態で起動できます。<br />
<br />
<h4>マーケットプレースへの提出の前に - Marketplace Testkit</h4>
マーケットプレースでは恐らく機械による自動テストと人間による手動テストでアプリの動作チェックが行われています。提出してから承認されるまでに数日を要することが多いため、テストの失敗を未然に防ぐために事前チェック項目のテストができる <span style="font-size: large; color:#00C0FF">Marketplace Testkit</span> というツールがあります。<br />
<br />
今回は Marketplace Testkit を使って提出前のテストを実施します。<br />
<br />
Visual Studio のメニュー→プロジェクト→Marketplace Testkit を開くを選択すると Marketplace Testkit を開始します。<br />
左の「アプリケーションの詳細」「自動テスト」「監視対象のテスト」「手動テスト」の順に進みます。<br />
<br />
<h5>アプリケーションの詳細</h5>
ここではマーケットプレースで必要となるアイコン、スクリーンショットを参照します。まずは大きなアプリケーション タイル、小さなアプリケーション タイル、Marketplace タイルを設定します。そしてアプリケーションのスクリーン ショットを1つ設定します。<br />
<br />
<h5>自動テスト</h5>
ここではプロジェクトの実行ファイル、アイコン、スクリーンショットが正常かどうかテストします。実施にはプロジェクトがリリース用にビルドされている必要があります。リリース用にビルドするには Visual Studio のツールバー上にある Debug を Release に切り替えてからメニューのビルド→ソリューションのビルドでビルドします。<br />
<br />
「テストの実行」ボタンを押すと下記のような結果が表示されます。<br />
<br />
<table>
<tr>
<th style="white-space:nowrap">結果</th>
<th>テスト名</th>
<th>テストの説明</th>
<th>結果の詳細</th>
</tr>
<tr>
<td style="white-space:nowrap">成功</td>
<td>XAP パッケージの用件</td>
<td>XAP ファイルサイズとコンテンツファイルの検証</td>
<td></td>
</tr>
<tr>
<td>成功</td>
<td>機能の検証</td>
<td>アプリケーションの機能の検証</td>
<td>[情報]：アプリケーションで使用される機能：ID_CAP_NETWORKING</td>
</tr>
<tr>
<td>成功</td>
<td>図像</td>
<td>アプリケーションのアイコンの検証</td>
<td></td>
</tr>
<tr>
<td>成功</td>
<td>スクリーンショット</td>
<td>スクリーンショットの検証</td>
<td></td>
</tr>
</table>
アイコンやスクリーンショットのサイズが正しくないと警告されます。また、機能の検証の結果の詳細に ID_CAP_NETWORKING と表示されて、このアプリがネットワークを利用することを自動検出してくれます。カメラや電話帳などにアクセスするコードが含まれる場合には ID_CAP_ISV_CAMERA や ID_CAP_CONTACTS などが表示されます。これらは WMAppManifest.xml ファイルに記載します。標準でほとんどの機能を「使う」ようになっていますが、アプリが利用する機能は自動判別なので特に開発者が ID_CAP_* を追加したり削除する必要はありません。特定の機能を利用するコードを書いた覚えがないのに ID_CAP_* が表示される場合は、どこかで利用されているのでチェックするなどします。<span style="color:#CCC">ただし、今回検出された ID_CAP_NETWORKING はネットワークを使わない場合でも付与されるらしく、全くネットワークを使わないアプリの場合には WMAppManifest.xml ファイルを編集して ID_CAP_NETWORKING を削除すれば検出されなくなります。</span><br />
<br />
<h5>監視対象のテスト</h5>
ここではテスト実施者がアプリケーションを実際に使用して、全ての操作を実施した場合の状況をテストします。このテストは実機で行う必要があります。Zune ソフトウェアを起動して、開発者アンロック状態の端末を接続して、端末の画面ロックを解除した状態で、Visual Studio のツールバー上のプロジェクトのターゲットを Windows Phone Device に切り替えます。<br />
<br />
「アプリケーションを起動」を押すと実機でアプリが起動するので、自分で操作します。<br />
<br />
今回はRSSフィードを表示する1ページのみなので、リストを下までスクロールして、上まで戻ることを何度か繰り返し、最後の「戻る」ボタンでアプリを終了します。しばらくすると結果が表示されます。<br />
<br />
<table>
<tr>
<th style="white-space:nowrap">結果</th>
<th>テスト名</th>
<th>テストの説明</th>
<th>結果の詳細</th>
</tr>
<tr>
<td style="white-space:nowrap">成功</td>
<td>起動時間</td>
<td>アプリケーションの起動時間の検証です。</td>
<td>[警告]：アプリケーションの起動に 5.2 秒かかりました。これは、起動時間が 5 秒という許容範囲に迫っています。</td>
</tr>
<tr>
<td>成功</td>
<td>ピーク時のメモリ消費量</td>
<td>アプリケーションのピーク時のメモリ消費量の検証</td>
<td>[情報]：アプリケーションで使用されるピーク メモリは 15.84 MB です。</td>
</tr>
<tr>
<td>成功</td>
<td>アプリケーションの終了</td>
<td>すべての例外が処理され、アプリケーションが予期せず終了されていないことの検証です。</td>
<td>[情報]：ハンドルされない例外は発生しませんでした。例外が発生して処理されている場合は、アプリケーションでユーザー フレンドリなメッセージが表示され、応答していることを確認してください。</td>
</tr>
<tr>
<td>成功</td>
<td>[戻る] ボタンの仕様</td>
<td>[戻る] ボタンを押したときの適切な動作の検証です。</td>
<td></td>
</tr>
</table>
起動時間の項目で警告がでています。実装方法に問題があるのかも知れませんが今回はテストアプリなのでこのままにします。<br />
その他、アプリのピーク時のメモリ消費量が多い場合や、ハンドルされていない例外が発生した場合、戻るボタンのテストが正しく実施されていない場合などに警告がでます。<br />
<br />
<h5>手動テスト</h5>
これは、アプリケーションのページ遷移の挙動や応答速度などのテストすべき項目を手動でテストして成功・失敗を付けていくチェックシートです。今回は割愛します。<br />
<br />
<h4>マーケットプレースへの提出</h4>
今回は <span style="font-size: large; color:#00C0FF">社内テスト</span> 用に <span style="font-size: large; color:#00C0FF">プライベート ベータテスト</span> 向けにアプリを提出します。<br />
マーケットプレースへのアプリの提出手順については App Hub の下記のページに詳しく載っています。<br />
<br />
<a href="http://create.msdn.com/ja-jp/home/about/submit_walkthrough/submit_apps_walkthrough" target="_blank">App Hub - Windows Phone 7 アプリの提出フロー </a><br />
<span style="font-size: large"><a href="http://create.msdn.com/ja-jp/home/about/submit_walkthrough/submit_apps_betatest" target="_blank">プライベート ベータテストにアプリを提出する手順の説明</a></span> ← これを見ながら<br />
<br />
以下のような手順です。<br />
<br />
<ol>
<li>App Hub で実行ファイルをアップロードする</li>
<li>説明を入力する</li>
<li>画像をアップロードする</li>
<li>ベータテスターのメールアドレスを入力する</li>
<li>提出完了</li>
<li>App Hub から完了通知のメールが届く</li>
<li>ダウンロードリンクをベータテスターへ通知</li>
<li>ベータテスターが実機にてダウンロードする</li>
<li>ベータテスターが実機にてレビュー（星の数とコメント）を投稿する</li>
</ol>
<span style="font-size: large; color:#00C0FF">社内テスト</span>を行う際は、テストを行う実機端末がサインインしている Windows Live ID を <span style="font-size: large; color:#00C0FF">ベータテスターのメールアドレス</span> を入力してくださいの欄に入力します。<span style="font-size: large; color:#00C0FF">メールアドレスは最大 100 件</span> まで入力できるようです。<span style="font-size: large; color:#00C0FF">テストを行う実機端末は開発者アンロックされている必要はありません</span>。<br />
<br />
マーケットプレースへの提出が完了して、しばらくすると <span style="font-size: large; color:#00C0FF">Congratulations! テストアプリ for Windows Phone is now available to the Windows Live ID participants you named as reviewers. という内容のメール</span>が届いて、そのメール内に<span style="font-size: large; color:#00C0FF">テストアプリのダウンロードリンク</span>が書かれているので、そのダウンロードリンクをテスターに通知してテストしてもらいます。<br />
<br />
プライベート ベータテスト向けに配布したアプリは他からは見えないので、個人レベルであればアプリの <span style="font-size: large; color:#00C0FF">レビュー機能</span> を使って不具合報告をすることで、App Hub 内で<span style="font-size: large; color:#00C0FF">レビュー結果（星の数とコメント）を閲覧</span>することができます。社内テストであれば独自のバグ追跡システムなどで管理するでしょう。<br />
<br />
テストが完了したら App Hub 内で「ベータを終了」を指示することで、ベータテスターへの配布が停止します。また、<span style="font-size: large; color:#00C0FF">プライベート ベータテスト向けに配布したアプリの有効期限は90日</span>であり、それを過ぎるとダウンロードできなくなります。<br />
<br />
全てのテストが完了すれば、今度は 、<span style="font-size: large; color:#00C0FF">パブリック Marketplace</span> の方に提出することで、正式リリースとなります。<br />
<br />
<br />
<br />
<h3>おわり</h3>
以上が Windows Phone 7.5 の<span style="font-size: large; color:#00C0FF">アプリ開発</span>-<span style="font-size: large; color:#00C0FF">社内テスト</span>-<span style="font-size: large; color:#00C0FF">マーケットプレースへの提出</span>の流れとなります。<br />
<br />
次回はアプリ開発時のTIPSなどを紹介します。<br />
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66795111" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66819913.html">
<title>#isucon 追加表彰式の様子＆ふりかえり</title>
<link>http://blog.livedoor.jp/techblog/archives/66819913.html</link>
<description>ライブドア開発本部の tagomoris です。 
先日最終結果をお伝えいたしました #isucon ですが、下記エントリの通り当日は表彰できなかった準優勝チームがありました。申し訳ありませんでした。 
livedoor Techブログ : ISUCONやりましたーっ！　最終結果発表 #isucon 
なんと...</description>
<dc:creator>tagomoris</dc:creator>
<dc:date>2011-09-07T14:28:30+09:00</dc:date>
<dc:subject>ISUCON</dc:subject>
<content:encoded><![CDATA[<p>ライブドア開発本部の tagomoris です。</p> <br>
<p>先日最終結果をお伝えいたしました #isucon ですが、下記エントリの通り当日は表彰できなかった準優勝チームがありました。申し訳ありませんでした。</p> <br>
<p><a href="http://blog.livedoor.jp/techblog/archives/66780326.html" rel="nofollow">livedoor Techブログ : ISUCONやりましたーっ！　最終結果発表 #isucon</a></p> <br>
<p>なんと、この「team_karakani」さんにライブドアにお越しいただけるとのことで、追加で表彰式を行いました！</p> <br>
<p>大会委員長の伊勢より準優勝賞金三万円の目録授与。</p> <br>
<p><a href="http://pics.livedoor.com/u/kushii_/8768591" target="_blank"><img border="0" src="http://img.pics.livedoor.com/012/e/1/e11a23cc51abcc94157a-L.JPG" /></a></p><br>
<p>チーム「team_karakani」のお二人(三人チームで、本日はお二人にお越しいただきました)。おめでとうございます！</p> <br>
<p><a href="http://pics.livedoor.com/u/kushii_/8768593" target="_blank"><img border="0" src="http://img.pics.livedoor.com/011/0/a/0ac5c050703c1af44eeb-L.JPG" /></a></p> <br>
<p>当日の方針と実施内容をうかがうと、以下のようなあたりだったようです。</p> <br>
<ol style="padding-left:16px;margin-left:16px"><li>DBのスキーマ変更 (articleテーブルへのコメント最終投稿日時カラムの追加)</li> <br>
<li>静的ファイルのリバースプロキシへの配置</li> <br>
<li>HTMLレンダリング結果のキャッシュ(未完)</li> <br>
<li>DBサーバでもアプリケーションサーバを起動</li></ol> <br>
<p>DBサーバでもアプリケーションサーバを起動というのは他であまり聞かれなかった点ですね。</p> <br>
<p>なお運営側から当日の状況を振り返りますと「追加でサーバを1台お渡しします、ただし申請があった場合に限り、その際に用途を聞きます」というレギュレーション項目がありました。このサーバですが実は <strong>申請チームは5チームのみ</strong> という状況で、実際には時間内に4台のサーバに十分に手を入れるだけでもかなり手いっぱいだったかな、とは思っています。お聞きした用途の内訳は以下の通り。(うろ覚えですが。)</p> <br>
<ul style="padding-left:16px;margin-left:16px"><li>キャッシュサーバに使う (2チーム)</li> <br>
<li>アプリケーションサーバの追加に使う (2チーム)</li> <br>
<li>(自信なさそうに)たぶんJob Queue用に使う (1チーム)</li></ul> <br>
<p>イベント後の感想などを見るに、やはり7時間弱という時間は「考えたことをやりきる」には多少短いという声が多いようです。次回は合宿で、という声もありますが、みなさん参加したいですか？ 自分も参加者として参加したいです！ だ、誰か！ どこか主催してもいいという方はいらっしゃいませんか！！１！</p> <br>
<p>先日公開した自家製 isucon セットもあちこちで試していただけているようで嬉しい限りです。手元での気分転換や技術磨き、仲間内でのお遊びなど、楽しくお使いください。</p> <br>
<p>最後に改めまして、ISUCONにご参加いただいた皆様、ご注目いただいた皆様、本当にありがとうございました。今後ともライブドア、およびライブドア技術部会をよろしく御願い致します。</p> <br>
 <br>
<h4>ISUCON関連記事</h4> <br>
<ul style="padding-left:16px;margin-left:16px"><br>
<li><a href="http://blog.livedoor.jp/techblog/archives/66780326.html" rel="nofollow">livedoor Techブログ : ISUCONやりましたーっ！　最終結果発表 #isucon</a></li> <br>
<li><a href="http://blog.livedoor.jp/techblog/archives/66785336.html" rel="nofollow">livedoor Techブログ : 写真と動画で振り返る #isucon オフィシャルレポート</a></li> <br>
<li><a href="http://blog.livedoor.jp/techblog/archives/66784747.html" rel="nofollow">livedoor Techブログ : 自家製 #isucon のつくりかた</a></li></ul> <br>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66819913" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66785336.html">
<title>写真と動画で振り返る #isucon オフィシャルレポート</title>
<link>http://blog.livedoor.jp/techblog/archives/66785336.html</link>
<description>こんにちは、ライブドア技術部会の櫛井です。

2011年8月27日(土)に開催された、いい感じにスピードアップコンテスト、略して
ISU Contest (Iikanjini Speed Up Contest)  #isucon ですが、すでに沢山の方々に
イベントのレポートなどをいただいており、ありがとうございます...</description>
<dc:creator>kushii_</dc:creator>
<dc:date>2011-08-30T18:39:04+09:00</dc:date>
<dc:subject>ISUCON</dc:subject>
<content:encoded><![CDATA[こんにちは、ライブドア技術部会の櫛井です。<br>
<br>
2011年8月27日(土)に開催された、いい感じにスピードアップコンテスト、略して<br>
<b>ISU Contest (Iikanjini Speed Up Contest)  #isucon</b> ですが、すでに沢山の方々に<br>
イベントのレポートなどをいただいており、ありがとうございます。<br>
このエントリでは写真と動画で #isucon を振り返ってみたいと思います。<br>
<br>
<br>
場所は新宿エルタワー。割と最近できた会議室で行われました。<br>
当日はこのような案内が出てました。ISUCON！<br>
<a href="http://pics.livedoor.com/u/kushii_/8732080" target="_blank"><img border="0" src="http://img.pics.livedoor.com/012/8/d/8d795b384051e4dd5900-L.JPG" /></a><br>
<br>
まずはイベントで最も重要な会場内のネットワーク設営から。<br>
弊社ネットワーク事業部のプロがサクサク作業しておりますが、実は当日になって<br>
当初打ち合わせで聞いていた回線種類と違うことが判明したものの、会社が近いという<br>
こともあり無事に乗り切れました。会社近くの会場にして正解でした。<br>
<a href="http://pics.livedoor.com/u/kushii_/8731965" target="_blank"><img border="0" src="http://img.pics.livedoor.com/012/4/c/4c3a1a3872f7be28f64e-L.JPG" /></a><br>
<br>
<br>

<a href="http://blog.livedoor.jp/techblog/archives/66785336.html">続きを読む</a>
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66785336" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66784747.html">
<title>自家製 #isucon のつくりかた</title>
<link>http://blog.livedoor.jp/techblog/archives/66784747.html</link>
<description>こんにちは、ISUCON というイベントのレギュレーションを考えたり環境の準備をやったりコード書いたりしてた tagomoris です。普段はライブドア開発本部のインフラサービス部というところで働いてます。 
先日ISUCONは幸いにも大好評のうちに終了したのですが、へとへとにな...</description>
<dc:creator>tagomoris</dc:creator>
<dc:date>2011-08-30T14:30:24+09:00</dc:date>
<dc:subject>フリーソフト・フリーデータ</dc:subject>
<content:encoded><![CDATA[<p>こんにちは、ISUCON というイベントのレギュレーションを考えたり環境の準備をやったりコード書いたりしてた tagomoris です。普段はライブドア開発本部のインフラサービス部というところで働いてます。</p> 
<p>先日ISUCONは幸いにも大好評のうちに終了したのですが、へとへとになって疲れ切った状態で帰宅し、寝て起きてみると、公開しておいたソースコードをさっそく自分の手元で動かしている人がいました。説明とか何にもなかったのによくそこまで。どういうことなのと思わずにはいられません。</p> 
<p><a href="http://blog.riywo.com/2011/08/28/070009">#isucon に参加してきました＆isuconツールを試してみました - As a Futurist...</a></p> 
<p>また翌日にはTwitterでも続々と動かしてみた報告が見られ、エンジニアのみなさんのバイタリティには感服するばかりです。</p> 
 
<h4 id="content_1_2">ざいりょう</h4> 
<p>で、せっかくだから本番と同じデータで同じように試せるようにしたいよね、ということで、ソースコード一式に加えて初期データも用意しました！</p> 
<ul style="padding-left:16px;margin-left:16px"><li>ソースコード一式 (ベンチマーク対象アプリケーション、およびベンチマークツール一式)
<ul style="padding-left:16px;margin-left:16px"><li><a href="https://github.com/tagomoris/isucon" rel="nofollow">https://github.com/tagomoris/isucon</a></li> 
<li>(ISUCON本番時の状態のタグ) <a href="https://github.com/tagomoris/isucon/tree/ISUConRelease" rel="nofollow">https://github.com/tagomoris/isucon/tree/ISUConRelease</a></li></ul></li> 
<li>初期データファイル
<ul style="padding-left:16px;margin-left:16px"><li><a href="https://github.com/downloads/tagomoris/isucon/isucon_db.sql.gz">「こちら」</a>(gzip圧縮、約40MB)</li></ul></li></ul> 
<p>ソースコード一式についてですが、ISUCON本番から少しだけ変更を加えてあり、基本的には1台のPCでベンチ対象からベンチマークまで完結する設定・コードが最初から入っています。とりあえずお試しいただくにはこの状態からが多分やりやすいと思います。またベンチマークツールに多少のデバッグが行われています。<br /> 
ISUCON本番と同じように多数サーバ構成・多数チーム参加で動作させるにはリリースタグの状態でやるのがいいと思いますが、サーバ構成をどうするか次第の部分もあり、なかなか面倒です。試したい人は頑張ってください。どうしてもという場合には @tagomoris 宛にお聞きいただけると答えられるかもしれません。</p> 
<p>初期データファイルはISUCON本番のものと同じです。mysqldumpファイルなので、mysqlにそのまま食わせて使用できます。個人的なお勧めは、まずこのファイルを使わない状態でベンチマークを走らせ、その後にこのデータを入れてみることです。データの増大が(プログラムの構造によっては)性能にどれだけ影響を与えるかが実感できます。</p> 
 
<h4 id="content_1_3">したごしらえ</h4> 
<p>ISUCON環境を作成するPCについてですが、以下の環境のどれかを想定しています。</p> 
<ul style="padding-left:16px;margin-left:16px"><li>Linux系OSのどれか
<ul style="padding-left:16px;margin-left:16px"><li>ISUCONは CentOS 5.6 でしたが、CentOS 6 やDebian系のものでも問題ないと思います</li></ul></li> 
<li>Mac OSX
<ul class="list2" style="padding-left:16px;margin-left:16px"><li>10.6 Snow Leopard を手元では使用していますが、10.7 Lion でも多分大丈夫です</li> 
<li>Xcode のインストールがおそらく必要です(入ってない環境が手元にないので確認できない……)</li></ul></li></ul> 
<p>BSD系のOSやSolaris等でも気合いを入れれば動くような気がしますが、確認していません。基本的に以下のものが動くことが大前提です。</p> 
<ul class="list1" style="padding-left:16px;margin-left:16px"><li>MySQL 5.5 (5.1でも多分動く)</li> 
<li>Apache 2.2 (無くてもどうにかなる)</li> 
<li>git</li> 
<li>perl 5.8 以降</li> 
<li>node.js 0.4.11 (0.4系の新しめのものなら大丈夫そうだが v0.4.11 おすすめ)</li> 
<li>supervisord
<ul style="padding-left:16px;margin-left:16px"><li>easy_install 経由で入れる(後述)</li></ul></li></ul> 
<p>特に node.js で環境が選ばれるかもしれません。node.js 0.4系はWindowsに対応していないので、WindowsだけでISUCON環境を作ることは残念ながら不可能です。(0.5を使ってもしかしたら動くかもしれませんが、全く試していません。試された方がいましたら教えてくださると嬉しいです。)</p> 
<p>準備としてApacheとMySQLをなんとか入れます。ApacheはOSXは最初から入っていますし、MySQL 5.5はLinuxでもOSXでも公式のものが用意されていますので、自分の環境にあわせてインストールして下さい。このあたりはあちこちに案内があるので割愛します。<br /> 
またperlも対象となる環境ではどれでも最初から使えるので省略します。perlのバージョンを変えて遊んだりしたい気持ちはよくわかりますが説明が大変なので、みなさまで各自頑張ってください。もしくは誰かがblogエントリを書いてくれると思います。</p> 
<p>node.jsはちょっとレアなので書きます。nvm というnode.js自体のバージョンを管理するツール経由で入れるのが簡単です。naveという同種の目的のツールもありますので好み次第かなとも思いますが、とりあえず自分のとっている方法で。</p> 
<ul style="padding-left:16px;margin-left:16px"><li><a href="https://github.com/creationix/nvm" >https://github.com/creationix/nvm</a></li></ul> 
<p>このREADMEに従って以下のコマンドを叩きインストールします。ついでに必要なモジュールもインストールしてしまいましょう。</p> 
<pre>$ git clone git://github.com/creationix/nvm.git ~/.nvm
$ . ~/.nvm/nvm.sh
$ nvm install v0.4.11
$ nvm use v0.4.11
$ nvm alias default v0.4.11
$ npm install express jade mysql jsdom async</pre> 
<p>これでnodeおよびnode用モジュールのパスは以下のようになるはずです。</p> 
<ul style="padding-left:16px;margin-left:16px"><li>nodeのパス: ~/.nvm/v0.4.11/bin/node</li> 
<li>モジュールのディレクトリ: ~/node_modules/</li></ul> 
<p>違ったなら nvm の動作が変わったのかもしれません。node.jsまわりにはよくあることなので、動揺せず適宜読み替えてください。</p> 
<p>またアプリケーションやベンチマーク管理ツールなどをデーモンとして動作させるため supervisord をインストールします。<br /> 
無くても試すだけは試せますが、スコアを求めてあれこれやる上ではあった方が便利です。easy_install コマンド経由でインストールするので、その準備をしておいてください。</p> 
<pre>$ sudo easy_install supervisor</pre> 
 
<h4 id="content_1_4">つくりかた</h4> 
<p>なにはともあれ、ソースコードを取得します。適当なディレクトリを選んで git clone しましょう。isuconディレクトリの中に展開されます。</p> 
<pre>$ git clone git://github.com/tagomoris/isucon.git
$ cd isucon</pre> 
<p>まずWebアプリケーションから動作させることにしましょう。データベースにユーザを作成したりスキーマを定義したりします。</p> 
<pre>$ mysql -u root &lt; webapp/config/database/isucon.sql</pre> 
<p>Perlでアプリケーションを動作させるには以下の手順でOKです。( webapp/perl/README に書いてある通りです。cpanmはインストール済みなら curl や chmod は不要です。)</p> 
<pre>$ cd webapp/perl
$ curl -k -L http://cpanmin.us/ &gt; ./cpanm
$ chmod +x ./cpanm
$ ./cpanm -Lextlib -n --installdeps .
$ perl -Mlib=extlib/lib/perl5 extlib/bin/plackup -s Starman -E production --preload-app app.psgi</pre> 
<p>最後のコマンドを実行すると <a href="http://localhost:5000/" rel="nofollow">http://localhost:5000/</a> でWebアプリケーションにアクセスが可能になるはずです。ブラウザで開いてみてください。<br /> 
最初の時点では記事が何もないので何も表示されませんが、ISUCONロゴをクリックすると記事投稿画面になり、そこから記事が投稿できます。ひとつ記事を投稿すればそれに対してコメントをつけたりもできるようになり、ブラウザ上にあれこれ表示されるようになってきます。<br /> 
しばらくこのperlのプロセスは起動したままにしておきましょう。作業は別のターミナルを開いてやることにします。</p> 
<p>最後にリバースプロキシとしてApacheの設定を行います。(なくてもとりあえず動くので、省略しても構いません。)<br /> 
基本的には単純で、ApacheがListenしている port 80 に来たリクエストを、すべてlocalhost:5000に転送します。</p> 
<pre>ProxyRequests Off
 
&lt;Proxy *&gt;
  Order deny,allow
  Allow from all
&lt;/Proxy&gt;
 
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/</pre> 
<p>mod_proxy (およびAPサーバを複数立てる場合には mod_proxy_balancer)を有効にしたApacheに上記の設定をします。OSXなら /etc/apache2/other/isu.conf などといったファイルを作成し、そこに書いておけば良いでしょう。Linuxの場合は /etc/httpd/conf.d/isu.conf に書く場合や /etc/apache2/site-enabled/default に追記すると良い場合があります。<br /> 
書いたらApacheに設定を読み込ませます。</p> 
<pre>$ sudo apachectl restart</pre> 
<p>これで <a href="http://localhost/" rel="nofollow">http://localhost/</a> でさっきのアプリケーションが見られるようになりました。なりましたよね？<br /></p> 

<p>ベンチマークの準備にもいくつかの手順が必要です。まず http_load をビルドします。</p> 
<pre>$ cd tools
$ tar xzf http_load/http_load-12mar2006.tar.gz
$ cd http_load-12mar2006
$ patch -p1 &lt; ../http_load/http_load.patch
$ make</pre> 
<p>このとき、<a href="http://blog.nomadscafe.jp/2011/08/http-load-isucon.html">恐怖のkazeburoパッチ</a>をpatchコマンドで当てています。当てなくても動作はしますが、よりリアルなISUCON環境のためにはぜひとも当てるべきでしょう。<br /> 
続けてperlのスクリプト用のモジュールの準備。</p> 
<pre>$ cd ../
$ ../webapp/perl/cpanm -Lextlib -n JSON Furl</pre> 
<p>もしリバースプロキシを立てない場合は、ベンチマークの設定ファイルの編集が必要です。tools/config.json を次のように書き換えましょう。(リバースプロキシのApacheを立てた場合はこの変更は不要です。)</p> 
<pre>--- config.json	2011-08-28 21:51:02.000000000 +0900
+++ config.json.2	2011-08-29 19:08:15.000000000 +0900
@@ -10,6 +10,6 @@
     &quot;team01&quot; 
   ],
   &quot;teams&quot;: {
-    &quot;team01&quot;: {&quot;id&quot;:&quot;team01&quot;, &quot;name&quot;:&quot;oreore&quot;, &quot;pass&quot;:&quot;pass&quot;, &quot;bench&quot;:&quot;bench01&quot;, &quot;target&quot;:&quot;127.0.0.1:80&quot;}
+    &quot;team01&quot;: {&quot;id&quot;:&quot;team01&quot;, &quot;name&quot;:&quot;oreore&quot;, &quot;pass&quot;:&quot;pass&quot;, &quot;bench&quot;:&quot;bench01&quot;, &quot;target&quot;:&quot;127.0.0.1:5000&quot;}
   }
 }  </pre> 
<p>target の指定のところでポート番号を変更していますね。ここだけで大丈夫です。</p> 
<p>ここまでやれば、コマンドラインベースでのベンチマークは動作します(そのようなオプションをISUCON後に追加しました)。以下のコマンドを実行しましょう！</p> 
<pre>$ NODE_PATH=lib node bench.js team01 standalone</pre> 
<p>実行すると1分間、すごい勢いでアプリケーションにリクエストが飛びます。1分経過後、ベンチマークおよびWebアプリケーション動作チェックの結果が次のように表示されればOKです。(これはtagomorisのMacBookAirで実行した結果。)</p> 
<pre>tools tagomoris$ NODE_PATH=lib node bench.js team01 standalone
{ teamid: 'team01',
 resulttime: Mon, 29 Aug 2011 10:02:48 GMT,
 test: true,
 score: 7102,
 bench: 
  { fetches: 7102,
    'max parallel': 10,
    bytes: 245187000,
    seconds: 60.0002,
    'mean bytes/connection': 34523.6,
    'msecs/connect': { mean: 0.378283, max: 36.007, min: 0.081 },
    'msecs/first-response': { mean: 12.754, max: 1254.57, min: 0.906 },
    response: { success: 7102, error: 0 },
    responseCode: { '200': 7102 } },
 checker: 
  { checker: { summary: 'success' },
    poster: { summary: 'success' } } }</pre> 
<p>ここに出ている &quot;test:true&quot; が動作チェックにパスしたということ、そして &quot;score: 7102&quot; がベンチマークの結果のスコアです。当日はみんなでこの数値を競っていたわけですね。これであなたもISUCON参加者！<br /> 
なおここに表示されたデータ(およびこれから後に書く方法で実行されたベンチマークのデータ)はすべて tools/data 下に保存され、後から確認できます。</p> 
 
<h4 id="content_1_5">もりつけ</h4> 
<p>実質的にはここまでで動くのですが、このままではちょっと見た目が残念ですし、コードや設定に変更を加えた場合にもいろいろと面倒です。なので、まず各種ツールが常時起動した状態になるようにします。<br /> 
これが完了すると、ISUCONのように21チーム準備した場合にはこんな画面が見られるわけですね！</p> 
<div align="center"><a href="http://livedoor.blogimg.jp/techblog/imgs/3/9/3948d03b.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/3/9/3948d03b-s.png" width="320" height="142" border="0" alt="master" hspace="5" class="pict"  /></a></div>
<p>このために supervisord を使用します。他にも daemontools など同種のツールがありますが、supervisordのシンプルさにひかれて今回はこれを使いました。<br /> 
以下の作業を始める前に、前の方で perl コマンドを叩いて起動しっぱなしにしていたプロセスは ctrl-C して停止させておきましょう。</p> 
<p>スコアはデータベースに格納されますので、そのためのスキーマをMySQLに導入します。以下のコマンドで一発です。</p> 
<pre>$ mysql -u root &lt; tools/etc/master.sql</pre> 
<p>で、おひとり様用のsupervisord.conf全部入りを作りましたので、これを使うのが楽です。が、その前に各種パス用の設定ファイルを修正します。</p> 
<pre>$ cd isucon
$ cat standalone/env.sh
#!/bin/bash
 
USERNAME=tagomoris
USER_HOME=/Users/tagomoris
NODE_VERSION=v0.4.11
 
export PATH=$PATH:$USER_HOME/.nvm/$NODE_VERSION/bin
export NODE_PATH=$NODE_PATH:$USER_HOME/node_modules/</pre> 
<p>ここで USERNAME および USER_HOME はnvmのインストールなどをしたユーザ名およびそのホームディレクトリを入れておきます。このあたりは普通 $HOME を使えばいいのですが supervisord を使う場合は root から呼ばれる場合などもあるので、このようにしてあります。<br /> 
また NODE_VERSION や PATH や NODE_PATH には nvm 関連のパス等をセットしています。これはインストール後に確認したご自分の環境に合わせてください。</p> 
<p>これが終わったら、次に standalone/supervisord.conf を /etc/ 以下にコピーし、自分の環境にあわせて書き換えます。</p> 
<pre>$ sudo cp standalone/supervisord.conf /etc/
$ sudo vi /etc/supervisord.conf</pre> 
<p>ログファイルの場所や細かいパラメータなどいろいろありますが、とりあえず動作させるために書き換えるのは以下の7ヶ所に埋まっている、isuconリポジトリの場所、およびユーザ名だけです。</p> 
<pre>[program:master]
command=/Users/tagomoris/Documents/isucon/tools/etc/master.sh
process_name=isucon bench master
user=tagomoris
...
 
[program:agent]
command=/Users/tagomoris/Documents/isucon/tools/etc/agent.sh
process_name=isucon bench agent
user=tagomoris
...
 
[program:isucon_perl]
directory = /Users/tagomoris/Documents/isucon/webapp/perl
command=perl -Mlib=/Users/tagomoris/Documents/isucon/webapp/perl/extlib/lib/perl5 /Users/tagomoris/Documents/isucon/webapp/perl/extlib/bin/plackup -s Starman -E production --preload-app --disable-keepalive --workers 10 /Users/tagomoris/Documents/isucon/webapp/perl/app.psgi
user=tagomoris</pre> 
<p>ここに /Users/tagomoris/Documents/isucon とあるのが自分がOSX上でisuconのリポジトリを置いた場所ですね。これをみなさんのPC上のパスにあわせて変更してください。 program:isucon_perl の command 行には何ヶ所かに埋まっているので修正漏れがないようにしてください。<br /> 
また user も何ヶ所かにありますが、これはあなたのユーザ名に変更してください。</p> 
<p>変更が終わったら sudo supervisord -n とすると、その端末内で supervisord が立ち上がり master.js と agent.js および perl のアプリケーションをすべて起動します。何か修正ミスなどがあればこのときにエラーになるので、端末内に表示される supervisord のエラーログ、あるいは /tmp/isucon.perl.log や /tmp/isucon.master.log などとして作成される各ツールのログを確認してください。<br /> 
さらっと書いてきましたが、master/agentとは以下のような役割のプログラムです。</p> 
<ul style="padding-left:16px;margin-left:16px"><li>master
<ul style="padding-left:16px;margin-left:16px"><li>ベンチマークのスコアを各チームについて表示したり、ベンチマークの起動を指示したりするためのツール</li> 
<li>起動していれば <a href="http://localhost:3080/" rel="nofollow">http://localhost:3080/</a> でアクセスできる</li></ul></li> 
<li>agent
<ul style="padding-left:16px;margin-left:16px"><li>masterからのベンチマーク起動の指示を受け取って bench.js を実行したり、ベンチマークの走行状況がどのようになっているかを報告したりするためのツール</li> 
<li>特にベンチマークをかける側を複数台のサーバに分散したりする場合にこのようなものが必要</li> 
<li>人が直接見られる画面はなし</li></ul></li></ul> 
<p>supervisord を起動して問題なく各プロセスが上がるようになれば、あとはもう sudo supervisord だけで起動してバックグラウンドにいってもらっても大丈夫です。</p> 
<p>supervisord 経由で各プロセスが無事に起動していれば、以下のように「記録なし！」な画面が出てきますね。チームがひとつなのはちょっとさびしいですが、おひとり様用なのでしょうがありません。<br /> 
&quot;idle&quot; をクリックするとベンチマークを起動できますので、初期パスワード &quot;pass&quot; を入力して &quot;START&quot; をクリックすれば状態が &quot;running&quot; となります。無事ベンチマークが完走したらチーム名の部分が青くなると同時にスコアが表示され、さあチューニングのはじまりだ！</p> 
<p>
<a href="http://livedoor.blogimg.jp/techblog/imgs/0/0/00146fa2.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/0/0/00146fa2-s.png" width="320" height="199" border="0" alt="1" hspace="5" class="pict"  /></a><a href="http://livedoor.blogimg.jp/techblog/imgs/c/3/c342450c.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/c/3/c342450c-s.png" width="320" height="194" border="0" alt="2" hspace="5" class="pict"  /></a><a href="http://livedoor.blogimg.jp/techblog/imgs/3/9/39adac5b.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/3/9/39adac5b-s.png" width="320" height="187" border="0" alt="3" hspace="5" class="pict"  /></a>
 </p>
<h4 id="content_1_6">かくしあじ</h4> 
<p>ここまでで初期データのないISUCON環境ができて、成績の数値も出てきました。6000とかすごいスコアですねISUCON上位に入れるじゃん！ と思ったあなた、初期データの導入をお忘れですね。<br /> 
ページ先頭のリンクから初期データ isucon_db.sql.gz をダウンロードし、適当な場所に置いておきます。次のようなコマンドで MySQL に読み込ませましょう。</p> 
<pre>$ gzcat isucon_db.sql.gz | mysql -uroot</pre> 
<p>完了後にそのままもういちどベンチマークを回してみると……</p> 
<div align="center"><img src="http://livedoor.blogimg.jp/techblog/imgs/a/3/a38951fe.png" width="284" height="222" border="0" alt="d1" hspace="5" class="pict"  /></div>
<p>スコアなんとたったの58・・・！ <strong>俺たちのISUCON坂はまだはじまったばかりだ！</strong> という気分になりますね！ (サーバでの動作とはいえ)<strong>ISUCON優勝チームが1分だと90,000のスコアを叩き出していた</strong>ことを考えるとどれだけ先が長いかがわかります。</p> 
<p>またPCでの実行で、かつベンチマーク対象もベンチマーク元も同じPCになっていると、デフォルトの状態でも &quot;FAILED&quot; となることがあります。その表示をクリックしてみるとこんなダイアログが出るので確認してください。</p> 
<div align="center"><a href="http://livedoor.blogimg.jp/techblog/imgs/9/3/939633de.png" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/9/3/939633de-s.png" width="320" height="103" border="0" alt="2" hspace="5" class="pict"  /></a></div>
<p>理由としては負荷をかけたときにサーバが重過ぎて、表示内容のチェックを行うためのHTTPリクエストがぜんぜん通ってないんですね。HTMLの内容を確認することができず、レギュレーション上のチェックが通らないため、そのまま FAILED となっています。<br /> 
根本的な原因はアプリケーションが重過ぎることですが、特にリバースプロキシにApacheを立てていて、かつプロセス数が少ないような場合にこういうことが起こります。お使いの環境で以下の項目をチェックしてみてください。</p> 
<ul style="padding-left:16px;margin-left:16px"><li>Apache のプロセス数が少なすぎる数になっていないか</li> 
<li>Apache の設定で keepalive が有効になっていないか
<ul style="padding-left:16px;margin-left:16px"><li>参考: <a href="http://blog.nomadscafe.jp/2011/08/http-load-isucon.html">チート対策とhttp_loadに仕掛けた罠の話 #isucon </a></li> 
<li>Mac OSX のApache2はデフォルトで有効なので注意！</li></ul></li> 
<li>そもそも非力すぎるマシンで実行していないか</li></ul> 
<p>どうしてもFAILEDが消せない場合、以下の対策を複合すればとりあえず通るようになるかもしれません。</p> 
<ol style="padding-left:16px;margin-left:16px"><li>リバースプロキシのApacheを使うのをやめてベンチマークをアプリケーションに直接向ける
<ul style="padding-left:16px;margin-left:16px"><li>tools/config.json の変更を行うこと</li></ul></li> 
<li>Perl版アプリケーションをやめてNode.js版を使う
<ul style="padding-left:16px;margin-left:16px"><li>アプリケーション単体での高負荷耐性はNode.js版の方が良いです</li> 
<li>supervisord.conf でPerl版アプリケーションの設定セクションをコメントアウトし、Node.js版の側のコメントアウトを外してから supervisord を起動します</li> 
<li>各種パスの修正に気をつけてやってあれば、そのまま起動するはずです</li></ul></li></ol> 
<p>さて、実はこの「おひとり様用」の設定は http_load の並列度をわざと2に落としています。これは初期状態でのベンチマークが通りやすくするためですね。パフォーマンスが十分に高い環境では並列度はもっと上げた方がスコアは上がります。<br /> 
ISUCON本戦では http_load の並列度は 10 という設定に固定してありました。あなたのアプリケーションが高スコアを叩き出すようになってきたら、この数値に戻してみてもいいでしょう。tools/bench.js の9行目を変更してお試しください。</p> 
 
<h4 id="content_1_7">できあがり</h4> 
<p>これで環境は完成です。思う存分にあなたのISUCONをお楽しみください！ 高得点をゲットできたらblogなどに書いていただけると我々もとても嬉しいです。</p> 
<p>ライブドアではISUCONと楽しく激しく格闘できるエンジニアを募集しています！</p> 

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66784747" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66780326.html">
<title>ISUCONやりましたーっ！　最終結果発表 #isucon</title>
<link>http://blog.livedoor.jp/techblog/archives/66780326.html</link>
<description>ライブドア技術部会の伊勢幸一です。

去る 2011年 8月 27日(土曜日で隅田川花火大会の日)、いい感じにスピードアップコンテスト ISUCONを開催しました。参加者の皆さん、見学者の皆さん、関係者の皆さん、おつかれさまでした！あんど、ありがとうございました。おかげさまで...</description>
<dc:creator>techblog</dc:creator>
<dc:date>2011-08-29T14:03:16+09:00</dc:date>
<dc:subject>ISUCON</dc:subject>
<content:encoded><![CDATA[ライブドア技術部会の伊勢幸一です。<br>
<br>
去る 2011年 8月 27日(土曜日で隅田川花火大会の日)、いい感じにスピードアップコンテスト <b>ISUCON</b>を開催しました。参加者の皆さん、見学者の皆さん、関係者の皆さん、おつかれさまでした！あんど、ありがとうございました。おかげさまで予想以上に盛り上がり、つぶやきやブログエントリー等を見る限り皆さんに楽しんでいただけたようで、スタッフ一同開催してよかったと心から思っています。また、副賞の書籍をご提供して頂いた<a target="_blank" href="http://gihyo.jp/">技術評論社</a>様にこの場をお借りして心より御礼申し上げます。技評さんはエンジニアの味方ですねっ！（あたりまえかｗ）<br>
<br>
ここで、改めまして、コンテストの最終結果発表をさせて頂きます。<br>
<br>
<b><font size="+4" color="#0000ff">と、その前に ・・・・　</font></b><br>
<br>
コンテスト終了後、即時計測の結果に基づき優勝1チーム、準優勝1チームを表彰させていただきましたが、その際、最終的な結果確認の段階で得点のチェックにミスがありました。単純な得点出力の目視確認ミスです。「team_karakani」の得点がスタッフのチェックにおいて見過ごされていました。大変申し訳ありません。目視はいけませんね。<br>
<br>
また単純な点数では「team_karakani」が2位で「いんふらえんじにあー」が3位ですが、スコアの差が 1.5%に収まるという僅差であり性能誤差を考えるとランク付けが極めて難しい状況でした。<br>
<br>
そこで、今回は準優勝を２組にして表彰する事としました。というわけで、最終結果発表ですっ！<br>
<blockquote><b><font size="+2" color="#ff0000">優勝</font><font size="+2"> チーム　fujiwara組　</font></b><br>
　スコア <b>272,004 query / 3min</b><br>
　優勝賞金　6万円(　現金！）<br>
　チャンピオントロフィー<br>
　技術評論社 「オンラインゲームを支える技術」「Vyatta入門」各3冊<br>
<br>
<b><font size="+2" color="#ff0000">準優勝 foo</font><font size="+2">　チーム　team_karakani</font></b><br>
　スコア 80,160 query / 3min<br>
　準優勝賞金 3万円 ( 現金！）<br>
<br>
<b><font size="+2" color="#ff0000">準優勝 bar</font><font size="+2">　チーム　いんふらえんじにあー</font></b><br>
　スコア 78,989 query / 3min<br>
　準優勝賞金 3万円 ( 現金！）<br>
</blockquote><br>
<br>
圧倒的じゃないか、fujiwara組は。テストベンチ時間は3分ですので、1分あたり約9万クエリ、毎秒1,500クエリを処理している事になります。1,500 query/sec っていうと比較的アクセスタフな実サービスでもかなり実用的なパフォーマンスではないでしょうか？ただし、今回の課題は初見のはずなので、初見のアプリをたった6時間でここまで仕上げるというのは脅威的な実力でしょう。すげぇ！<br>
<br>
<strike>本エントリーを書いている時点で</strike>これまでに見つけた参加者等のエントリーはこちら！(適宜追加)<ul><br>
<b>参加者レポート</b><br><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/sfujiwara/20110827/1314460582"> #isucon で優勝してきました/酒日記 はてな支店(チームfujiwara組)</a><br>
<li><a target=_blank" href="http://d.hatena.ne.jp/sfujiwara/20110829/1314597283">#isucon ではどんなことを考えながら作業していたか/酒日記 はてな支店(チームfujiwara組)</a><br>
<li><a target="_blank" href="http://www.songmu.jp/riji/archives/2011/08/isucon.html"> #isucon で優勝させてもらってきました/おそらくはそれさえも平凡な日々(チームfujiwara組)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/sugyan/20110829/1314626174">#isucon で優勝したチームのメンバーとして参加してた/すぎゃーんメモ (チーム　fujiwara組)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/tmatsuu/20110827/1314467819"> isuconに参加してきた＆チーム「いんふらえんじにあー」の戦略など/それ、Gentooだとどうなる？(チーム　いんふらえんじにあー）</a><br>
<li><a target="_blank" href="http://netmark.jp/2011/08/isucon.html">isuconに参加してきました/netmark.jp(チーム　いんふらえんじにあー）</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/ishikawa84g/20110828">isucon に参加してきた。/やったるでぇ (チーム　いんふらえんじにあー）</a><br>
<li><a target="_blank" href="http://mindia.jp/book/karakani/entry/6110">#isucon に行ってきました team_karakaniチーム)/カラカニのメモ帳 (チーム　team_karakani)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/do_aki/20110827/1314460762"> ISUCON に参加してきました/do_akiの徒然想記 (くまさんちーむ)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/karupanerura/20110828/1314469620">#isucon に参加してきました。/かるぱねるらすたいる (チーム　WHK）</a><br>
<li><a target="_blank" href="http://blog.riywo.com/2011/08/28/070009"> #isucon に参加してきました＆isuconツールを試してみました/As a Futurist…(チームやすべえ)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/kamipo/20110829/1314645281">#isucon に参加してやったこと思ったこと/かみぽのメモ(チームやすべえ)</a><br>
<li><a target="_blank" href="http://blog.myfinder.jp/2011/08/isucon.html">#isuconの結果を反省 または私は如何にして心配するのを止めてパラメタ設定を細かくいじるることに終始したのか/MYFINDER'S BLOG(チーム　真夏のサイクロンウェーブ)</a><br>
<li><a target="_blank" href="http://blog.livedoor.jp/xaicron/archives/52593057.html">ISUCON に参加して FAIL してきました！/にひりずむ::しんぷる (チーム　真夏のサイクロンウェーブ)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/gfx/20110829/1314627301">ISUCONのウェブアプリのテンプレートエンジンはXslateでした/Islands in the byte stream(チーム　真夏のサイクロンウェーブ)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/a666666/20110827/1314576816">#isucon に応募した /刺身☆ブーメランのはてなダイアリー(チーム　情熱会)</a><br>
<li><a target="_blank" href="http://blog.tnmt.info/2011/08/28/isucon-01/">#isucon に参加してきました/blog.tnmt.info(チーム　情熱会)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/memememomo/20110829/1314625233">isuconに参加してきました/メメメモモ(チーム 京都スイーツ)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/inuz/20110830/p1">ISUCONに参加してきた/inuzの日記(チーム　ツヤマ倶楽部)</a><br>
<li><a target="blank" href="http://d.hatena.ne.jp/futsu-9/20110903/p1">isuconに行って平凡な記録を残してきた/フツーな日常 (チーム　team fsck)</a></ul><br>
<b>運営側レポート</b><ul><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/tagomoris/20110827/1314458440">isucon終了に寄せて(tagomorisのメモ置き場)</a><br>
<li><a target="_blank" href="http://blog.nomadscafe.jp/2011/08/http-load-isucon.html">チート対策とhttp_loadに仕掛けた罠の話 #isucon (blog.nomadscafe.jp)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/tagomoris/20110829/1314587772">#isucon ベンチでいかにチートするか: その1 - 敵はhttp_load(tagomorisのメモ置き場)</a><br>
<li><a target="_blank" href="http://d.hatena.ne.jp/hideden/20110828/1314490713"> isuconお遊びチーム（事前社内β組）の設定あれこれ(Perlとかmemoとか日記とか。)</a><br>
<li><a target="_blank" href="http://blog.livedoor.jp/faulist/archives/1732537.html"> #isucon で学ぶWebアプリの高速化の話(As Sloth As Possible)</a><br>
<li><a target="_blank" href="http://blog.kushii.net/archives/1635785.html">エンジニアがやりたいというので 技術コンテスト #isucon の運営をしてみた(blog::941)</a></ul><br>
<br>
<b>ライブドアTech Blog関連記事</b><ul><br>
<li><a target="_blank" href="http://blog.livedoor.jp/techblog/archives/66736413.html">Webアプリケーション高速化バトル #isucon 見学エリア設置のお知らせ</a><br>
<li><a target="_blank" href="http://blog.livedoor.jp/techblog/archives/66528186.html">なんでもありのWebアプリケーション高速化バトル、#isucon 開催のお知らせ</a><br>
<li><a target="_blank" href="http://blog.livedoor.jp/techblog/archives/66595391.html">【締め切りました】Webアプリケーション高速化バトル、#isucon 詳細と参加者募集開始</a><br>
<li><a target="_blank" href="http://blog.livedoor.jp/techblog/archives/66768375.html">【リマインダー】Webアプリケーション高速化バトル(ISUCON) 【いよいよ明日開催！】</a></ul><br>
<br>
懇親会もほぼ全員参加で(お二方だけご都合が悪く欠席、残念）、とにかく楽しかったの一言です。次があるかどうかわかりませんが（誰かやって！）、今後ともライブドア、およびライブドア技術部会をよろしく御願い致します。<br>
<br><br>
ISUCONのレポートエントリーは後ほど公開します。<br>
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66780326" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66768375.html">
<title>【リマインダー】Webアプリケーション高速化バトル(ISUCON) 【いよいよ明日開催！】</title>
<link>http://blog.livedoor.jp/techblog/archives/66768375.html</link>
<description>ライブドア技術部会の伊勢幸一です。いよいよ明日8月27日(土)  いい感じにスピードアップコンテスト　ISUCON　が開催されます。


そこで、参加者、見学者の方々に改めてご案内いたします。お忙しいところ恐縮ですが、内容ご確認頂ければ幸いです。

※明日詳細※

開催概要
...</description>
<dc:creator>techblog</dc:creator>
<dc:date>2011-08-26T14:45:14+09:00</dc:date>
<dc:subject>お知らせ</dc:subject>
<content:encoded><![CDATA[<div class="section">
<p>ライブドア技術部会の伊勢幸一です。いよいよ明日8月27日(土) <b> いい感じにスピードアップコンテスト</b>　ISUCON　が開催されます。</p>
<p><center><img src="http://livedoor.2.blogimg.jp/techblog/imgs/d/e/dece2b0e.jpg"></center></p>

<p>そこで、参加者、見学者の方々に改めてご案内いたします。お忙しいところ恐縮ですが、内容ご確認頂ければ幸いです。</p>

<p>※明日詳細※</p>

<p><h2>開催概要</h2></p>

<p>開催：ISUCON ~Iikanjini Speed Up CONTEST~</p>
<p>主催：株式会社ライブドア 技術部会</p>
<p>日時：2011年8月27日(土) 11:00-19:00(開場10:00-)</p>
<p>場所：新宿エルタワー 1F サンスカイルーム (東京都新宿区西新宿1-6-1)</p>

<p><h2>アクセス</h2></p>
<p>1) JR新宿駅 西口地下広場から直結、ビル内奥のエスカレーターで1Fへ</p>
<p>   (参考) <a href="http://www.sunskyroom.jp/l_tower/floor.htm">http://www.sunskyroom.jp/l_tower/floor.htm</a></p>
<p>2) A18出口横、左にあるエルタワーの階段を1Fまで登ると  サンスカイルーム前に出ます。会場は1F外側から直接入れる場所になります。ビル内エスカレーター等に、案内もございますので、1Fフロアにでましたら、一度外に出て頂ければ会場までお越し易いかと存じます。</p>


<p><h2>会場について</h2></p>
<p>・喫煙所は会場外、ビルの吹き抜け部分にあります。</p>
<p>・<strike>現在1Fトイレが工事中のため、恐れ入りますが他フロアのトイレをご利用頂くことになります。</strike></p>
<p><span style="color: #FF0000;">本日確認時点で1Fのトイレは利用可能でした。工事中は2Fトイレになります。</span></p>
<p>・B1フロアにファミリーマートがありますので、必要に応じてこちらもご利用ください。</p>
<p>・B2フロアにレストラン街がございますが、昼食等、  近辺のお店にアクセスしやすいようになっております。</p>

<p><h2>スケジュール</h2></p>

<p>10:00- 開場 </p>
<p>11:00- 開会挨拶</p>
<p>       参加チーム紹介</p>
<p>       ルール説明 他</p>
<p>       ※終了後そのまま競技に移ります。</p>
<p>       </p>
<p>	|</p>

<p>18:00  競技終了</p>
<p>       採点、表彰、講評</p>

<p>19:00  終了</p>
<p>       移動後懇親会</p>


<p>※10:00から開場致しますので、11:00 10分前までに  会場にお越しいただければ幸いです。</p>


<p><h2>ご連絡事項</h2></p>

<p>・作業用に、無線LANが使用可能なノートPCをそれぞれ  お持ちください。</p>

<p>・サーバ情報、及び、ネットワーク情報につきましては、当日会場にてお知らせ致します。</p>

<p>・事前にお知らせ頂きましたチーム情報につきましては、 開会後のチーム紹介の際に利用させて頂きます。</p>

<p>・会場入口にて受付をしておりますので、代表者の方はチーム名とメンバーの出欠について、ご連絡下さい。  参加証をお渡しします。  (受付の際に、写真等顔出しNGの方いらっしゃいましたらお申し出下さい)</p>

<p>・ISUCON について、Blog等での発表は自由になります。  写真撮影も自由となりますが、参加者の方の写真については  他の参加者の方へご確認頂ければ幸いです。</p>

<p>・軽食の持ち込みについては可能です。  (会場ビル内にも自動販売機等ございます)</p>

<p>・お菓子、お茶、珈琲をご用意しております。</p>


<p><h2>当日のご連絡先</h2></p>

<p>当日何かございましたら、こちらまでご連絡下さい。</p>
<p>                Twitter ハッシュタグ：#isucon</p>


<p><h2>懇親会について</h2></p>

<p>会  場：地酒とそば・京風おでん 三間堂 新宿エルタワー店</p>
<p>        <a href="http://r.gnavi.co.jp/ga3v220/">http://r.gnavi.co.jp/ga3v220/</a></p>
<p>場  所：新宿エルタワーB2F</p>
<p>参加費：3,480円(飲み放題つきコース料理です)</p>

<p>※参加費は受付時から、懇親会開始前までに徴収致しますので 恐れ入りますが、事前にご準備頂ければ幸いです。</p>

<p>以上、それでは、明日お会いできるのを楽しみにお待ちしております。</p>

<p>皆さま！全力で楽しみましょうっ！</p>
</div>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66768375" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66736413.html">
<title>Webアプリケーション高速化バトル #isucon 見学エリア設置のお知らせ</title>
<link>http://blog.livedoor.jp/techblog/archives/66736413.html</link>
<description>こんにちは、ライブドア技術部会の櫛井です。

予想以上の早さで参加者申し込みが定員に達したIikanjini Speed Up Contest 略して ISUCONですが見学エリアを設置することにしましたのでお知らせいたします。特に申し込みなどは不要ですので当日お越しいただき「見学希望です...</description>
<dc:creator>kushii_</dc:creator>
<dc:date>2011-08-19T14:36:46+09:00</dc:date>
<dc:subject>お知らせ</dc:subject>
<content:encoded><![CDATA[<div class="section">
<p>こんにちは、ライブドア技術部会の櫛井です。</p>

<p>予想以上の早さで参加者申し込みが定員に達した<b>Iikanjini Speed Up Contest 略して ISUCON</b>ですが見学エリアを設置することにしましたのでお知らせいたします。特に申し込みなどは不要ですので当日お越しいただき「見学希望です」とスタッフへお伝えいただければOKです。(見学エリアには電源の用意はありません、ご注意ください) 見学者への注意事項としまして、見学エリアからの実在の椅子の投擲は禁止となっております。ご注意ください。</p>
<p>なお、<b>参加者優先となりますので、見学希望社多数の場合入場をお断りすることがございます</b>。あらかじめご承知おきください。</p>


<p>また、有料となりますが「懇親会にも参加したいよ！」というアグレッシブな方は #isucon@freenode へjoinし、櫛井宛でご連絡ください。締め切りは8月25日となります（ドタキャン厳禁です）。不明な点は Twitter にハッシュタグ #isucon でお問い合わせください。</p>

<p><h3>会場情報</h3></p>
<ul>
<li>会場</li>
</ul>
<p>新宿エルタワー</p>
<ul>
<li>日程</li>
</ul>
<p>8月27日 10:00～19:00 (18:00作業終了、以降 結果測定、表彰、講評)</p>
<p>19時より懇親会を開催します。</p>





<p><h3>関連エントリ</h3></p>
<p><a href="http://blog.livedoor.jp/techblog/archives/66528186.html" target="_blank">livedoor Techブログ : なんでもありのWebアプリケーション高速化バトル、#isucon 開催のお知らせ</a></p>
<p><a href="http://blog.livedoor.jp/techblog/archives/66595391.html" target="_blank">livedoor Techブログ : 【締め切りました】Webアプリケーション高速化バトル、#isucon 詳細と参加者募集開始</a></p>

</div>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66736413" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66266188.html">
<title>スマートフォンでお手軽3D</title>
<link>http://blog.livedoor.jp/techblog/archives/66266188.html</link>
<description>こんにちわ。最近引っ越した家の周りを探索するのにはまっている中村です。
今回は3D関係について書きたいと思います。
なお、サンプル画像と動画が記事の最後にあります!!
 
概要

iPhoneのOpenGL用にさまざまなライブラリおよびミドルウェアは出ていますけれど、今回は、iP...</description>
<dc:creator>tarotaro_naka</dc:creator>
<dc:date>2011-08-02T10:00:50+09:00</dc:date>
<dc:subject>iphone</dc:subject>
<content:encoded><![CDATA[こんにちわ。最近引っ越した家の周りを探索するのにはまっている中村です。<br />
今回は3D関係について書きたいと思います。<br />
なお、サンプル画像と動画が記事の最後にあります!!<br /><br />
 
<h3>概要</h3><br />

iPhoneのOpenGL用にさまざまなライブラリおよびミドルウェアは出ていますけれど、今回は、iPhoneの3Dチップメーカーが出しているライブラリの紹介をしたいと思います。一応公式のチップメーカーがだしているし、便利でお手軽なライブラリなのにいまいち検索しても日本語のサイトが出てこないので、開発の方に広く知ってもらいたいと思い、書こうと思いました。<br /><br />

iPhoneやAndroidのOpenGL Viewの使い方は一部紹介しますが、検索すればいくらでも出てくるのでそこは調べてもらうものとします。また、スキンドメッシュの原理に関しては、ちょこっとだけ解説しますが、詳しくは長くなるので、グラフィックスの専門のサイトにまかせてライブラリそのものの使い方について書きたいと思います。<br /><br />

<h3>ライブラリを出しているメーカーについて</h3><br />

ライブラリを出しているメーカーは<a href="http://www.imgtec.com/" target="_blank">Imagination社</a>という会社で、古くはゲーム機のDreamCastの3DチップメーカーとしてPowerVRを開発したメーカーです。そのメーカーがiPhone用の3Dチップを作っているというのも面白いですね。そこがiPhone用、Android用にスキンメッシュ（ポリゴンにつなぎ目がなく曲げることができる技術）まで対応したライブラリを開発してくれています。<br /><br />

<h3>ライブラリについて</h3><br />

車輪の再発明（時には大事ですが）をしなくとも、お手軽に3Dのデータを表示できるのでありがたく使わせてもらいましょう。もちろんチップメーカーが開発しているので、速度面に関してもいうことはなく最適化されていますし、MAYA、3DStudioMax、Blenderという商用のお高いソフトからフリーの3Dソフトまで対応していて、3Dのデータを出力してくれるプラグインまで開発してくれているので、フリーの環境でそろえたいという方から、商用のソフトはあるんだけどプラグインまで開発したくないなぁという方まで、便利に使えるSDKのセットになっています。<br /><br />

また、ある一部のゲームメーカーのプラットフォームで標準になっている3DのXML形式のColladaからも、ライブラリで使用できるPodという形式（アニメーション付き3Dフォーマット）に変換できるようになっています。<br /><br />

<h3>スキンメッシュの原理の簡単な説明</h3><br />

3Ｄオブジェクトとボーン（関節のような頂点を変形するもの）の関係は下の図のようになっています。<br /><br />

<div align="center"><table>
  <tr>
    <td align="center"><img src="http://livedoor.blogimg.jp/techblog/imgs/d/b/db288cff.png" width="129" height="474" border="0" alt="bone" hspace="5" class="pict" align="left"  /></td>
</tr></table></div>
<br />
この図をみると、3Ｄのオブジェクトに対してピンク色の菱形の物体が内部にはいっていると思います。<br /><br />

そのピンク色のボーンと呼ばれる物体が3Ｄオブジェクトの頂点をどの程度移動するかそれぞれの頂点に保存されており、この値をウェイトと呼びますが、このウェイト値とボーンの回転とか移動とかのマトリックスを乗算して頂点をどの程度まげるか決め、頂点に乗算し3Ｄポリゴンを変形します。<br /><br />

<h3>このライブラリを使う利点と欠点</h3><br />

このライブラリを使う利点は、お手軽に他のミドルウェアにありがちな、細かい処理が見えにくいということがなく、シンプルに3Dのアニメーションオブジェクトを表示することができることと、その割には、MAYA、3DStudioMax、Blenderという3つのソフトに対応していることです。<br /><br />

ただし弱点もあって、細かい仕様になりますが、4つ以上のサーフェース（マテリアルをもつポリゴン）にボーンがまたがって影響を及ぼすようなモデルには対応していないということです。まぁゲームとかですと、1サーフェースでUV（テクスチャを貼付けるための値）を1つだけ持つのが多かったりするし、そこは我慢しましょう。<br /><br />

<h3>iPhoneの場合</h3><br />

<h4>準備</h4><br />
まず、SDKをダウンロードしてきましょう、日本のImaginationのサイトもあるのですが、SDKが本家のサイトからダウンロードしてきた方が最新なので、本家から持ってきましょう。<br /><br />

登録してSDKをダウンロードしてきます。OpenGLES2.0のSDKのライブラリはShaderを使ったものになっていて、使いにくいので、1.0のSDKを持ってきます。<br /><br />

1.0のImaginationのSDKは、iPhoneのSDKのバージョンが古いもので作られたものらしく、バージョンの変更や、一部ソースを書き換えなくてはサンプルなどがコンパイルできなくなっていますが、ライブラリは特に変更しなくとも利用することが可能です。<br /><br />

<h4>ライブラリを変更するまえにOpenGLを利用できるViewについて</h4><br />

OpenGLを利用するためにちょっとUIViewを継承したViewを作る必要があります。<br /><br />

XCodeには、標準でOpenGLのViewを作るためのウィザードがあるので、それで作ったEAGLViewというのを改造して今回のライブラリが利用できるように変更しましょう。<br /><br />

ViewにはContextというものがあるのですが、そのGL用のContextには今のところ2種類ありまして、gl~Matrix（glPushMatrixとか）が使えないマトリックスを全部シェーダーで書かなければいけないモードと、gl~Matrix系の関数はすべて使えてシェーダーを使わないで構築するモードとがあります。<br /><br />

今回のライブラリはマトリックスを使ってやるライブラリになっていますので、それを使います。<br /><br />

ウィザードで作られたOpenGL Viewは、両方に対応していて、kEAGLRenderingAPIOpenGLES2というモード（マトリックスが使えないモード）が使えない場合は、kEAGLRenderingAPIOpenGLES1というモードを使うようになっています。ただし、iphone3GS以降はkEAGLRenderingAPIOpenGLES2が使えますので、強制的にkEAGLRenderingAPIOpenGLES1のモードを選択するようにしてやる必要があります。どちらかを選択する部分があると思いますのでそこを改造します。<br /><br />

あとは、drawFrame、または、renderメソッドに描画処理をいれたりすれば描画ができます。<br /><br />

<h4>お手軽に利用するには</h4><br />

サンプルにSkinningというもろに使えるサンプルがあるので、そこからソースを利用させてもらいましょう。ただし一般的に利用するためにはちょっと変更する必要があります。<br /><br />

<h4>サンプルを変更し自分用のライブラリへ</h4><br />

TutorialにSkinningというのがあるので、それのサンプルのなかにOGLESSkinning.cppというソースがあり、そのソースのテクスチャロードの部分のメソッドを変更します。<br /><br />

元のソースでは、テクスチャファイル名がハードコードされているので、マテリアルからテクスチャ名をとってきてテクスチャをロードする部分を作成します。<br /><br />

サンプルの方では、ライブラリの固有のテクスチャ圧縮形式であるpvr形式というものが使われているようですが、マテリアルの中に書いてあるファイル名は普通の画像形式（3Dソフトのプラグインから出力された時のテクスチャ名）が入っているので、それをロードするコーディングをします。<br /><br />

LoadTexturesメソッドの中身を書き換えて、PVRTextureLoadFromPVRを使ってテクスチャ画像をファイル名から読み込んでいる部分を書き換えます。具体的な書き換え方は、CoreGraphics系のライブラリを使って、画像を読み込み、それをglBindTextureとかglTexImage2Dとかを使って設定します。<br /><br />

<pre class="brush:objc;gutter:false;">
bool OGLESSkinning::LoadTextures(CPVRTString* const pErrorStr)
{
	/*if(PVRTTextureLoadFromPVR(c_szBodyTexFile, &m_uiBodyTex) != PVR_SUCCESS)
	{
		*pErrorStr = "ERROR: Failed to load body texture.";
		return false;
	}

	if(PVRTTextureLoadFromPVR(c_szLegTexFile, &m_uiLegTex) != PVR_SUCCESS)
	{
		*pErrorStr = "ERROR: Failed to load leg texture.";
		return false;
	}

	if(PVRTTextureLoadFromPVR(c_szBeltTexFile, &m_uiBeltTex) != PVR_SUCCESS)
	{
		*pErrorStr = "ERROR: Failed to load belt texture.";
		return false;
	}*/
	
	m_puiTextures = new GLuint[m_Scene.nNumMaterial];
	
	if(!m_puiTextures)
	{
		//*pErrorStr = "ERROR: Insufficient memory.";
		return false;
	}
	m_textureNum=0;
	for(int i = 0; i < (int) m_Scene.nNumMaterial; ++i)
	{
		m_puiTextures[i] = 0;
		SPODMaterial* pMaterial = &m_Scene.pMaterial[i];
		
		if(pMaterial->nIdxTexDiffuse != -1)
		{
			/*
			 Using the tools function PVRTTextureLoadFromPVR load the textures required by the pod file.
			 
			 Note: This function only loads .pvr files. You can set the textures in 3D Studio Max to .pvr
			 files using the PVRTexTool plug-in for max. Alternatively, the pod material properties can be
			 modified in PVRShaman.
			 */
			
			CPVRTString sTextureName = m_Scene.pTexture[pMaterial->nIdxTexDiffuse].pszName;
			int len = strlen(sTextureName.c_str());
			char * strc = (char *)malloc(sizeof(char)*(len+1));
			strcpy(strc,sTextureName.c_str());
			CPVRTString fullpath=CPVRTResourceFile::GetReadPath();
			len =strlen(fullpath.c_str());
			char * full = (char *)malloc(sizeof(char)*(len+1));
			strcpy(full,fullpath.c_str());
			NSString *patht= [[NSString alloc] initWithUTF8String:full];
			NSString *str = [[NSString alloc] initWithUTF8String:strc];
			NSString *pathname=[patht  stringByAppendingString:str];
			free(strc);
			free(full);
			
			CGImageRef image  = [UIImage imageWithContentsOfFile:pathname].CGImage;
			
			NSInteger  width  = CGImageGetWidth(image);
			NSInteger  height = CGImageGetHeight(image);
			GLubyte*   bits   = (GLubyte*)malloc(width * height * 4);
			CGImageAlphaInfo info;
			BOOL             hasAlpha;
			size_t           bitsPerComponent;
			info=CGImageGetAlphaInfo(image);
			//アルファ成分チェック
			hasAlpha=((info==kCGImageAlphaPremultipliedLast) || 
					  (info==kCGImageAlphaPremultipliedFirst) || 
					  (info==kCGImageAlphaLast) || 
					  (info==kCGImageAlphaFirst)?YES:NO);
			if (hasAlpha) {
				bitsPerComponent=kCGImageAlphaPremultipliedLast;
			} else {
				bitsPerComponent=kCGImageAlphaNoneSkipLast;
			}
            CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
			CGContextRef textureContext =
			CGBitmapContextCreate(bits, width, height, 8, width * 4,
								  colorSpace, bitsPerComponent);
			CGContextScaleCTM(textureContext, 1, -1);
			CGContextTranslateCTM(textureContext, 0, -(double)height);
			
			CGColorSpaceRelease(colorSpace);
			CGContextClearRect(textureContext,CGRectMake(0.0, 0.0, width, height));			
			CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, width, height), image);
			CGContextRelease(textureContext);
			
			glGenTextures(1, &m_puiTextures[i]);
			glBindTexture(GL_TEXTURE_2D, m_puiTextures[i]);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);
			
			glBindTexture(GL_TEXTURE_2D, 0);
			free(bits);
		}
	}
	return true;
}
</pre>
<br /><br />

<h4>CPVRTModelPOD型の変数の簡単な説明</h4><br />

CPVRTModelPODは3Dのシーンを管理しているクラスで、3Dシーンファイル（Pod形式）の読み込みのメソッドや、アニメーション部分のマトリックス（クォータニオン）の計算部分を自動でやってくれるクラスになっています。<br /><br />

CPVRTModelPODクラスに大してSetFrameして、あとはOpenGLのExtensionにマトリックスを突っ込んでやればオブジェクトの変形をしてくれるようになっています。こんな感じです。<br /><br />

<pre class="brush:objc;gutter:false;">
void OGLESSkinning::DrawModel()
{
	//Set the frame number
	m_Scene.SetFrame(m_fFrame);

	// Enable lighting
	if(lightsw)
		glEnable(GL_LIGHTING);
	else 
		glDisable(GL_LIGHTING);

	// Enable States
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	

	
	m_MeshNum=0;
	//Iterate through all the mesh nodes in the scene
	for(int iNode = 0; iNode &lt; (int)m_Scene.nNumMeshNode; ++iNode)
	{
		//Get the mesh node.
		SPODNode* pNode = &amp;m_Scene.pNode[iNode];

		//Get the mesh that the mesh node uses.
		SPODMesh* pMesh = &amp;m_Scene.pMesh[pNode-&gt;nIdx];

		// bind the VBO for the mesh
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[pNode-&gt;nIdx]);

		// bind the index buffer, won't hurt if the handle is 0
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[pNode-&gt;nIdx]);

		// Loads the correct texture using our texture lookup table
		if(pNode-&gt;nIdxMaterial == -1 )
			glBindTexture(GL_TEXTURE_2D, 0); // It has no pMaterial defined. Use blank texture (0)
		else
			glBindTexture(GL_TEXTURE_2D, m_puiTextures[pNode-&gt;nIdxMaterial]);

		//If the mesh has bone weight data then we must be skinning.
		bool bSkinning = pMesh-&gt;sBoneWeight.n != 0;

		if(bSkinning)
		{
			//If we are skinning then enable the relevant states.
			glEnableClientState(GL_MATRIX_INDEX_ARRAY_OES);
			glEnableClientState(GL_WEIGHT_ARRAY_OES);
			if(iNode==0)
			{
				if(m_fFrame==0)
				{
					m_max_vertex[0]=m_max_vertex[1]=m_max_vertex[2]=FLT_MIN;
					m_min_vertex[0]=m_min_vertex[1]=m_min_vertex[2]=FLT_MAX;
				}
				
				m_max_vertex_anim[0]=m_max_vertex_anim[1]=m_max_vertex_anim[2]=FLT_MIN;
				m_min_vertex_anim[0]=m_min_vertex_anim[1]=m_min_vertex_anim[2]=FLT_MAX;			}
		}
		else 
		{
			// If we're not using matrix palette then get the world matrix for the mesh 
			// and transform the model view matrix by it.
			PVRTMat4 worldMatrix;
			m_Scene.GetWorldMatrix(worldMatrix, *pNode);

			//Push the modelview matrix
			glPushMatrix();
			glMultMatrixf(m_mTransform.f);
			glMultMatrixf(worldMatrix.f);
			
			
		}

		// Set Data Pointers
		// Used to display non interleaved geometry
		
		glVertexPointer(pMesh-&gt;sVertex.n, GL_FLOAT, pMesh-&gt;sVertex.nStride, pMesh-&gt;sVertex.pData);
		glNormalPointer(GL_FLOAT, pMesh-&gt;sNormals.nStride, pMesh-&gt;sNormals.pData);
		if(pMesh-&gt;psUVW)
		{
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(pMesh-&gt;psUVW[0].n, GL_FLOAT, pMesh-&gt;psUVW[0].nStride, pMesh-&gt;psUVW[0].pData);
		}

		if(bSkinning)
		{
			//Set up the indexes into the matrix palette.
			m_Extensions.glMatrixIndexPointerOES(pMesh-&gt;sBoneIdx.n, GL_UNSIGNED_BYTE, pMesh-&gt;sBoneIdx.nStride, pMesh-&gt;sBoneIdx.pData);
			m_Extensions.glWeightPointerOES(pMesh-&gt;sBoneWeight.n, GL_FLOAT, pMesh-&gt;sBoneWeight.nStride, pMesh-&gt;sBoneWeight.pData);
		}

		// Draw

		
		int i32Strip = 0;
		int i32Offset = 0;

		for(int i32Batch = 0; i32Batch &lt;pMesh-&gt;sBoneBatches.nBatchCnt; ++i32Batch)
		{
			// If the mesh is used for skining then set up the matrix palettes.
			if(bSkinning)
			{
				//Enable the matrix palette extension
				glEnable(GL_MATRIX_PALETTE_OES);
				/*
					Enables the matrix palette stack extension, and apply subsequent
					matrix operations to the matrix palette stack.
				*/
				glMatrixMode(GL_MATRIX_PALETTE_OES);

				PVRTMat4	mBoneWorld;
				int			i32NodeID;

				//	Iterate through all the bones in the batch
				for(int j = 0; j &lt; pMesh-&gt;sBoneBatches.pnBatchBoneCnt[i32Batch]; ++j)
				{
					/*
						Set the current matrix palette that we wish to change. An error
						will be returned if the index (j) is not between 0 and
						GL_MAX_PALETTE_MATRICES_OES. The value of GL_MAX_PALETTE_MATRICES_OES
						can be retrieved using glGetIntegerv, the initial value is 9.

						GL_MAX_PALETTE_MATRICES_OES does not mean you need to limit
						your character to 9 bones as you can overcome this limitation
						by using bone batching which splits the mesh up into sub-meshes
						which use only a subset of the bones.
					*/

					m_Extensions.glCurrentPaletteMatrixOES(j);

					// Generates the world matrix for the given bone in this batch.
					i32NodeID = pMesh-&gt;sBoneBatches.pnBatches[i32Batch * pMesh-&gt;sBoneBatches.nBatchBoneMax + j];
					m_Scene.GetBoneWorldMatrix(mBoneWorld, *pNode, m_Scene.pNode[i32NodeID]);

					
					// Multiply the bone's world matrix by our transformation matrix and the view matrix
					mBoneWorld = m_mView * m_mTransform * mBoneWorld;

					// Load the bone matrix into the current palette matrix.
					glLoadMatrixf(mBoneWorld.f);
				}
			}
			else
			{
				//If we're not skinning then disable the matrix palette.
				glDisable(GL_MATRIX_PALETTE_OES);
			}

			//Switch to the modelview matrix.
			glMatrixMode(GL_MODELVIEW);

			// Calculate the number of triangles in the current batch
			int i32Tris;

			if(i32Batch + 1 &lt; pMesh-&gt;sBoneBatches.nBatchCnt)
				i32Tris = pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch+1] - pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch];
			else
				i32Tris = pMesh-&gt;nNumFaces - pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch];

			// Indexed Triangle list
			if(pMesh-&gt;nNumStrips == 0)
			{
				
					glDrawElements(GL_TRIANGLES, i32Tris * 3, GL_UNSIGNED_SHORT, &amp;((unsigned short*)0)[3 * pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch]]);
				
				
				
			}
			else // Indexed Triangle strips
			{
				int i32TrisDrawn = 0;

				while(i32TrisDrawn &lt; i32Tris)
				{
					
						glDrawElements(GL_TRIANGLE_STRIP, pMesh-&gt;pnStripLength[i32Strip]+2, GL_UNSIGNED_SHORT, &amp;((GLshort*)0)[i32Offset]);
										
					
					
					i32Offset += pMesh-&gt;pnStripLength[i32Strip]+2;
					i32TrisDrawn += pMesh-&gt;pnStripLength[i32Strip];

					++i32Strip;
				}
			}
		}
		
		if(!pMesh-&gt;sBoneBatches.nBatchCnt)
		{
			
				glDrawElements(GL_TRIANGLES, pMesh-&gt;nNumFaces*3, GL_UNSIGNED_SHORT, 0);
			
		}
		
		if(bSkinning)
		{
			glDisableClientState(GL_MATRIX_INDEX_ARRAY_OES);
			glDisableClientState(GL_WEIGHT_ARRAY_OES);

			// We are finished with the matrix pallete so disable it.
			glDisable(GL_MATRIX_PALETTE_OES);
		}
		else
		{
			//Reset the modelview matrix back to what it was before we transformed by the mesh node.
			glPopMatrix();
		}
	}

	
	
	
	
	// Disable States
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	// unbind the vertex buffers as we don't need them bound anymore
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	
	

}
</pre>
<br /><br />

<h3>Androidの場合</h3><br />

<h4>準備</h4><br />
Androidの場合もSDKをダウンロードしてきましょう。<br />
そのときにダウンロードしてくるのは、OpenGLES1.1のものをダウンロードしてきましょう。Androidの場合、OpenGLの部分はJavaではなく、C++で書かれているため、合わせてNDKを使ったアプリがコンパイルできる環境を準備しましょう。<br /><br />

<h4>お手軽に利用するには</h4><br />

Android版のほうはスキンアニメのサンプルがなぜか入ってないので、その部分を作らなければならないのですが、描画する部分はiPhone版のソースからそのまま持ってくれば使えるので大丈夫だと思います。<br /><br />

ただ、注意しなくてはならないのは、Android版は3Dのオブジェクトのデータをリソースなどに持っているのではなく、Cのソースにしてリンクしてそれを呼び出す感じになってしまっているので、それが嫌な場合は、Java側のソースでリソースのデータを/data/ディレクトリに書き出して、それをC側のソースから読み込んでやるようにしてやればよいと思います。<br /><br />

リソースをNDKで読み出す方法については、詳しくは検索してもらうとして、サンプルがないので0から作るのも大変なので、OGLESIntroducingPODを改造して作るとしましょう。<br /><br />

<h4>サンプルを変更し自分用のライブラリへ</h4><br />

まず、変更しなくてはいけないところはモデルを描画するところです。OGLESIntroducingPod.cppのOGLESIntroducingPOD::RenderSceneというメソッドの中身をちょっと変更します。そのメソッドの最後のほうにメッシュを描画している部分がありますが、その部分を全部コメントアウトして、独自のメソッドDrawModelを追加しましょう。<br /><br />

そのDrawModelメソッドは次の通りです（ほとんどiPhoneのソースから持ってきたものです）。<br /><br />

<pre class="brush:objc;gutter:false;">
void OGLESIntroducingPOD::DrawModel()
{
	//Set the frame number
	m_Scene.SetFrame(m_fFrame);

	// Enable lighting
	
	glEnable(GL_LIGHTING);
	

	// Enable States
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);	
	//Iterate through all the mesh nodes in the scene
	for(int iNode = 0; iNode &lt; (int)m_Scene.nNumMeshNode; ++iNode)
	{
		//Get the mesh node.
		SPODNode* pNode = &amp;m_Scene.pNode[iNode];

		//Get the mesh that the mesh node uses.
		SPODMesh* pMesh = &amp;m_Scene.pMesh[pNode-&gt;nIdx];

		// bind the VBO for the mesh
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[pNode-&gt;nIdx]);

		// bind the index buffer, won't hurt if the handle is 0
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[pNode-&gt;nIdx]);

		// Loads the correct texture using our texture lookup table
		if(pNode-&gt;nIdxMaterial == -1 || !texsw)
			glBindTexture(GL_TEXTURE_2D, 0); // It has no pMaterial defined. Use blank texture (0)
		else
			glBindTexture(GL_TEXTURE_2D, m_puiTextures[pNode-&gt;nIdxMaterial]);

		//If the mesh has bone weight data then we must be skinning.
		bool bSkinning = pMesh-&gt;sBoneWeight.n != 0;

		if(bSkinning)
		{
			//If we are skinning then enable the relevant states.
			glEnableClientState(GL_MATRIX_INDEX_ARRAY_OES);
			glEnableClientState(GL_WEIGHT_ARRAY_OES);
			
		}
		else 
		{
			// If we're not using matrix palette then get the world matrix for the mesh 
			// and transform the model view matrix by it.
			PVRTMat4 worldMatrix;
			m_Scene.GetWorldMatrix(worldMatrix, *pNode);

			//Push the modelview matrix
			glPushMatrix();
			glMultMatrixf(m_mTransform.f);
			glMultMatrixf(worldMatrix.f);
			
			
		}

		// Set Data Pointers
		// Used to display non interleaved geometry
		
		glVertexPointer(pMesh-&gt;sVertex.n, GL_FLOAT, pMesh-&gt;sVertex.nStride, pMesh-&gt;sVertex.pData);
		glNormalPointer(GL_FLOAT, pMesh-&gt;sNormals.nStride, pMesh-&gt;sNormals.pData);
		if(pMesh-&gt;psUVW)
		{
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
			glTexCoordPointer(pMesh-&gt;psUVW[0].n, GL_FLOAT, pMesh-&gt;psUVW[0].nStride, pMesh-&gt;psUVW[0].pData);
		}

		if(bSkinning)
		{
			//Set up the indexes into the matrix palette.
			glMatrixIndexPointerOES(pMesh-&gt;sBoneIdx.n, GL_UNSIGNED_BYTE, pMesh-&gt;sBoneIdx.nStride, pMesh-&gt;sBoneIdx.pData);
			glWeightPointerOES(pMesh-&gt;sBoneWeight.n, GL_FLOAT, pMesh-&gt;sBoneWeight.nStride, pMesh-&gt;sBoneWeight.pData);
		}

		// Draw


		int i32Strip = 0;
		int i32Offset = 0;



		for(int i32Batch = 0; i32Batch &lt;pMesh-&gt;sBoneBatches.nBatchCnt; ++i32Batch)
		{
			// If the mesh is used for skining then set up the matrix palettes.
			if(bSkinning)
			{
				//Enable the matrix palette extension
				glEnable(GL_MATRIX_PALETTE_OES);

				glMatrixMode(GL_MATRIX_PALETTE_OES);

				PVRTMat4	mBoneWorld;
				int			i32NodeID;

				//	Iterate through all the bones in the batch
				for(int j = 0; j &lt; pMesh-&gt;sBoneBatches.pnBatchBoneCnt[i32Batch]; ++j)
				{

				glCurrentPaletteMatrixOES(j);

					// Generates the world matrix for the given bone in this batch.
					i32NodeID = pMesh-&gt;sBoneBatches.pnBatches[i32Batch * pMesh-&gt;sBoneBatches.nBatchBoneMax + j];
					m_Scene.GetBoneWorldMatrix(mBoneWorld, *pNode, m_Scene.pNode[i32NodeID]);

					
					// Multiply the bone's world matrix by our transformation matrix and the view matrix
					mBoneWorld = m_mView  * mBoneWorld;

					// Load the bone matrix into the current palette matrix.
					glLoadMatrixf(mBoneWorld.f);
				}
			}
			else
			{
				//If we're not skinning then disable the matrix palette.
				glDisable(GL_MATRIX_PALETTE_OES);
			}

			//Switch to the modelview matrix.
			glMatrixMode(GL_MODELVIEW);

			// Calculate the number of triangles in the current batch
			int i32Tris;

			if(i32Batch + 1 &lt; pMesh-&gt;sBoneBatches.nBatchCnt)
				i32Tris = pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch+1] - pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch];
			else
				i32Tris = pMesh-&gt;nNumFaces - pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch];

			// Indexed Triangle list
			if(pMesh-&gt;nNumStrips == 0)
			{
				
					glDrawElements(GL_TRIANGLES, i32Tris * 3, GL_UNSIGNED_SHORT, &amp;((unsigned short*)0)[3 * pMesh-&gt;sBoneBatches.pnBatchOffset[i32Batch]]);
				
				
				
			}
			else // Indexed Triangle strips
			{
				int i32TrisDrawn = 0;

				while(i32TrisDrawn &lt; i32Tris)
				{
					
						glDrawElements(GL_TRIANGLE_STRIP, pMesh-&gt;pnStripLength[i32Strip]+2, GL_UNSIGNED_SHORT, &amp;((GLshort*)0)[i32Offset]);
									
					
					
					i32Offset += pMesh-&gt;pnStripLength[i32Strip]+2;
					i32TrisDrawn += pMesh-&gt;pnStripLength[i32Strip];

					++i32Strip;
				}
			}
		}
		
		if(!pMesh-&gt;sBoneBatches.nBatchCnt)
		{
			
				glDrawElements(GL_TRIANGLES, pMesh-&gt;nNumFaces*3, GL_UNSIGNED_SHORT, 0);
			
			
			
		}
		
		if(bSkinning)
		{
			glDisableClientState(GL_MATRIX_INDEX_ARRAY_OES);
			glDisableClientState(GL_WEIGHT_ARRAY_OES);

			// We are finished with the matrix pallete so disable it.
			glDisable(GL_MATRIX_PALETTE_OES);
		}
		else
		{
			//Reset the modelview matrix back to what it was before we transformed by the mesh node.
			glPopMatrix();
		}
	}

		
	// Disable States
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	// unbind the vertex buffers as we don't need them bound anymore
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

}
</pre>
<br /><br />

注意しなければならないのは、Android版の場合m_Extensionというクラス（OpenGL Extensionのメソッドをロードするクラス）がエクテンションの関数をロードできない（NDKには、Extensionの関数をロードする関数が実装されてない）ので、エクステンションの関数はOpenGLのextensionの関数そのまま使うようにしなければならないことです。<br /><br />

ただしここでも罠があって、そのままの状態だとNDKのOpenGL ESの関数定義には、matrix_palleteのExtensionが使える関数定義がされないでincludeされるので、glext.hがインクルードされる前にdefineで、次の定義をしておきます。<br /><br />

それがGL_GLEXT_PROTOTYPESで、<br /><br />

<pre class="brush:objc;gutter:false;">
#define  GL_GLEXT_PROTOTYPES
</pre>
<br /><br />
と、おまじない程度に書いておきましょう。<br /><br />

ここでは、テクスチャの部分も変えないと「pvr」という特殊な画像形式を読むようになっているのですが、そこはlibpngなどを使って、読み込み部分を書いたりするのでしょうが、検索すれば、NDKを使った読み込みの仕方が書いてあるサイトもあるので、そこを参照してください。また、もう一つ頂点をロードしている部分も書き換えます。次のように書き換えます。ここもiPhoneと一緒のコードです。<br /><br />

<pre class="brush:objc;gutter:false;">
bool OGLESIntroducingPOD::LoadVbos(CPVRTString* pErrorStr)
{
        if(m_Scene.nNumMesh == 0) // If there are no VBO to create return                                                        
                return true;
        if(!m_puiVbo)
                m_puiVbo = new GLuint[m_Scene.nNumMesh];

        if(!m_puiIndexVbo)
                m_puiIndexVbo = new GLuint[m_Scene.nNumMesh];


        glGenBuffers(m_Scene.nNumMesh, m_puiVbo);

        for(unsigned int i = 0; i &lt; m_Scene.nNumMesh; ++i)
          {
            SPODMesh&amp; Mesh = m_Scene.pMesh[i];
            unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;

            glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]);
            glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);                                                                 
            m_puiIndexVbo[i] = 0;

            if(Mesh.sFaces.pData)
              {
                glGenBuffers(1, &amp;m_puiIndexVbo[i]);
                uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]);
                glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);
              }
          }

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

        return true;
}
</pre>
<br /><br />

<h3>ライブラリ使用のサンプル</h3><br />

実際にライブラリを使用してサンプルを作ってみました。データ的には、秒間約50万ポリゴンぐらいですが、秒間100万ポリゴンぐらいでも大丈夫なようです。この数値がどのくらいかというと、PSPぐらいの性能というとわかりやすいんでしょうか。<br /><br /><br />

<h4>サンプル動画</h4><br />
<div align="center"><iframe width="425" height="349" src="http://www.youtube.com/embed/aHX60CG4Fu4" frameborder="0" allowfullscreen></iframe></div><br /><br />

<h4>サンプル画像</h4><br />
<table>
  <tr>
    <td><img src="http://livedoor.blogimg.jp/techblog/imgs/b/f/bf452319.png" width="320" height="480" border="0" alt="写真 3" hspace="5" class="pict" align="left"  /></td>
    <td><img src="http://livedoor.blogimg.jp/techblog/imgs/8/9/8972887b.png" width="320" height="480" border="0" alt="写真 2" hspace="5" class="pict" align="left"  /></td></tr>
<tr>
    <td><img src="http://livedoor.blogimg.jp/techblog/imgs/e/c/ec17be49.png" width="320" height="480" border="0" alt="写真 1" hspace="5" class="pict" align="left"  /></td> <td><img src="http://livedoor.blogimg.jp/techblog/imgs/1/f/1fb73ead.png" width="320" height="480" border="0" alt="写真" hspace="5" class="pict" align="left"  /></td> 
  </tr></table>
<table><tr><td><img src="http://livedoor.blogimg.jp/techblog/imgs/9/9/995c1fb4-s.png" width="320" height="213" border="0" alt="device" hspace="5" class="pict" align="left"  /></td></tr></table><br /><br />
<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66266188" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66595391.html">
<title>【締め切りました】Webアプリケーション高速化バトル、#isucon 詳細と参加者募集開始</title>
<link>http://blog.livedoor.jp/techblog/archives/66595391.html</link>
<description>【7/30 8:40 追記】
こちら定員の20チームとなりましたので締め切らせていただきます。お申し込みありがとうございました。応募された代表者へは別途ご連絡させていただきますので宜しくお願いいたします。
なお、何かしらの理由で参加者の方がキャンセルされた場合に再応募...</description>
<dc:creator>kushii_</dc:creator>
<dc:date>2011-07-29T17:00:33+09:00</dc:date>
<dc:subject>お知らせ</dc:subject>
<content:encoded><![CDATA[<div class="section">
<p>【7/30 8:40 追記】</p>
<p>こちら定員の20チームとなりましたので締め切らせていただきます。お申し込みありがとうございました。応募された代表者へは別途ご連絡させていただきますので宜しくお願いいたします。</p>
<p>なお、何かしらの理由で参加者の方がキャンセルされた場合に再応募を行う可能性もありますがそちらは別途アナウンスいたします。</p>

<ul>
<li>----------------------------------------------------------------------</li>
</ul>
<p>こんにちは、ライブドア技術部会の櫛井です。</p>



<p><img src="http://livedoor.blogimg.jp/techblog/imgs/d/e/dece2b0e.jpg" width="500" border="0" alt="isucon_logo" hspace="5" class="pict"  /></p>
<p><a href="http://blog.livedoor.jp/techblog/archives/66528186.html" target="_blank">先週お知らせした</a>通り <b>Iikanjini Speed Up Contest 略して ISUCON</b> の開催およびレギュレーションをお知らせいたします。また、このエントリの公開をもって参加者募集を開始します。<b>募集ページへのリンクはエントリ末尾<b></b></b>。先着順ですから要注目ですよ！</p>



<p><h3>レギュレーション概要</h3></p>
<p>レギュレーションは先日の告知時点から変更はありません。概要は以下の通りです。</p>

<ul>
<li>ライブドアブログから抽出したアクセスパターンの負荷をWebアプリケーションにかけ、GETリクエストの処理性能を競う
<ul>
<li>負荷パターンには一定量のデータ更新(POST)も含まれます</li>
</ul>
</li>
<li>対象Webアプリケーションは主催者からPerlで記述されたものが提供されます
<ul>
<li>および参考実装として Ruby と Node.js で記述されたものも提供される予定です</li>
<li>各実装はあくまで参考実装であり、デフォルト状態での各々の処理性能は一致しません</li>
</ul>
</li>
<li>負荷走行中にPOSTされたデータが1秒以内にGETリクエストへのレスポンスに反映されることとします</li>
<li>チーム単位(1～3人)での参加とし、チームごとに最大5台のLinuxサーバが与えられます
<ul>
<li>リバースプロキシ、Web/AP(2台)、DB、その他の用途(オプショナル)</li>
<li>全てのサーバは Xen 上の CentOS 5 です</li>
<li>Linux kernel や Linux ディストリビューション および OS そのものの入れ替えも禁止はしませんが Xen dom0 からの支援などは一切しません</li>
</ul>
</li>
<li>与えられたWebアプリケーションにおける以下の機能を変えないこととします
<ul>
<li>アクセス先のURI (IPアドレス、パス)</li>
<li>レスポンス(HTML)のDOM構造</li>
<li>ブラウザで表示した際の見た目(問題ない範囲で)、およびJavascript/CSSの効果</li>
<li>サーバ再起動を行っても設定・データの永続性が保たれていること</li>
</ul>
</li>
<li>以下の事項は特に禁止とします
<ul>
<li>主催者が他のチームへの妨害とみなす全ての行為</li>
<li>実在の椅子の投擲</li>
</ul>
</li>
</ul>

<p>上記が概要となります。正式なレギュレーション全文が<a href="http://blog.livedoor.jp/techblog/isucon/isucon_regulation.pdf" target="_blank">こちら</a>にあります。（PDFファイルです）参加予定の方はぜひご確認ください！</p>

<p><h3>表彰</h3></p>
<p>優勝・準優勝のチームには賞金および副賞があります。</p>
<ul>
<li>優勝チーム
<ul>
<li>賞金 ６万円、および副賞として <a href="http://gihyo.jp/" target="_blank">技術評論社様</a>よりWEB+DB PRESS plus書籍、Software Design plus書籍が贈られます（いずれもタイトルは現時点で未定）</li>
</ul>
</li>
</ul>

<ul>
<li>準優勝チーム
<ul>
<li>賞金 ３万円</li>
</ul>
</li>
</ul>

<ul>
<li>特別賞
<ul>
<li>賞金１万円</li>
</ul>
</li>
</ul>


<p><h3>募集要項</h3></p>
<p>以下の要項で参加者を募集します。ふるってご応募ください。</p>
<p> なお当日は、会場に若干ではございますがスイーツを準備してお待ちしています。</p>

<ul>
<li>日時
<ul>
<li>8月27日(土曜日) 11:00～19:00</li>
<li>開場は 10:00 を予定</li>
<li>競技は 18:00 で終了、以降で採点、表彰、講評など</li>
</ul>
</li>
<li>会場
<ul>
<li>新宿エルタワー サンスカイルーム C会議室 (1階)</li>
<li>JR新宿駅 西口地下広場から直結、ビル内、奥のエスカレーターで1Fへ</li>
<li>(参考) <a href="http://www.sunskyroom.jp/l_tower/floor.htm" target="_blank">http://www.sunskyroom.jp/l_tower/floor.htm</a></li>
</ul>
</li>
<li>募集人数
<ul>
<li>チーム単位で20チーム(先着順)</li>
<li>1チーム 1～3人とする</li>
</ul>
</li>
</ul>



<p>また19時から会場付近での懇親会(会費制)を予定しています。ぜひご参加ください。</p>


<p><h3>現時点での申し込み</h3></p>
<p>順次更新していきます。かっこ内はチーム人数。</p>

<p>1. smly (3)</p>
<p>2. 石川直人 (2)</p>
<p>3. @pekeq (3)</p>
<p>4. yut148 (1)</p>
<p>5. 原口秀人 (3)</p>
<p>6. kanonji (3)</p>
<p>7. xaicron (3)</p>
<p>8. walf443 (2)</p>
<p>9. @netmarkjp (3)</p>
<p>10. inuwarumono (3)</p>
<p>11. @164c (3)</p>
<p>12. 刺身 (2)</p>
<p>13. 黒猫さんチーム (1)</p>
<p>14. @karakani (3)</p>
<p>15. kamipo (3)</p>
<p>16. fujiwara (3)</p>
<p>17. くまさんちーむ (1)</p>
<p>18. ことりさんチーム (1)</p>
<p>19. fujya.sh (2)</p>
<p>20. nihen (2)</p>


<p><h3>申し込みフォーム</h3></p>
<p>こちらよりお申し込みください</p>
<p><a href="https://spreadsheets.google.com/a/livedoor.jp/spreadsheet/viewform?formkey=dFZtTVhqdGRIUlpFVjdPVDBRbXVSdFE6MQ" target="_blank">なんでもありのWebアプリケーション高速化バトル、#isucon 参加申し込みフォーム</a></p>






<p>ライブドアは、みなさまの挑戦をお待ちしています！</p>
</div>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66595391" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66560080.html">
<title>kanazawa.js v1.5　満員御礼</title>
<link>http://blog.livedoor.jp/techblog/archives/66560080.html</link>
<description>livedoor Techブログ : ライブドア技術部会　第二弾
こんにちわ。ライブドア技術部会　伊勢です。
先週土曜日、ライブドア技術部会協賛させてもらった kanazawa.js v1.5 - Hello Titanium Mobile ! が開催されました。



当日の様子は以下のリンクをご参照ください。

『kan...</description>
<dc:creator>techblog</dc:creator>
<dc:date>2011-07-25T16:24:28+09:00</dc:date>
<dc:subject>セミナー</dc:subject>
<content:encoded><![CDATA[<div class="section">
<p><a href="http://blog.livedoor.jp/techblog/archives/66289449.html" target="_blank">livedoor Techブログ : ライブドア技術部会　第二弾</a><br /></p>
<p>こんにちわ。ライブドア技術部会　伊勢です。<br></p>
<p>先週土曜日、ライブドア技術部会協賛させてもらった<a href="http://kanazawajs.tumblr.com/v1-5/" target+"blank"> kanazawa.js v1.5 - Hello Titanium Mobile ! </a>が開催されました。<br /></p>

<p><a href="http://livedoor.blogimg.jp/techblog/imgs/a/c/ac0f4a0e.jpg" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/a/c/ac0f4a0e-s.jpg" width="320" height="180" border="0" alt="DSC00392" hspace="5" class="pict" align="left"  /></a></p>

<p>当日の様子は以下のリンクをご参照ください。</p>

<p><span style="font-size: medium;"><a target="_blank" href="http://t32k.me/mol/log/kanazawa-js-v1-5/">『kanazawa.js v1.5 ー Hello Titanium Mobile! - 開催報告-』</a></span></p>

<p><span style="font-size: medium;"><a target="_blank" href="http://togetter.com/li/165175">Togetter - 「kanazawa.js v1.5 - Hello Titanium Mobile! -」</a></span></p>

<p>昨年、今年とスマフォ市場の勢いは目を見張る物があり、特に今年はiPhone端末に比べAndroidOS端末が各社出揃いはじめました。コンテンツ事業者としてはより大きい市場にサービスを提供するため、iPhoneだけではなく、Android向けのアプリケーションを開発しなければならなくなってきています。Androidの開発言語は基本的にJavaですが、今、JavaScriptでWebアプリのようにスマートフォンアプリを開発できるTitanium(チタニウムではなく、<b>タイタニウム</b>と読む)が注目されてきています。</p>

<p>今回のセミナーではそのTitaniumとは？といった基本的な情報から、Titaniumのハマリ所といったノウハウを判りやすく教えてもらえたようで、大盛況だったようです。</p>

<p>このTitaniumによって、いままでプログラマの仕事だったスマフォアプリの開発も次第にデザイナーやコーダーが直接実装していく事も可能であり、プログラマだけではなく、HTMLデザイナ、コーダにもお勧めかもです。<a href="http://livedoor.blogimg.jp/techblog/imgs/1/3/132781df.jpg" target="_blank"><img src="http://livedoor.blogimg.jp/techblog/imgs/1/3/132781df-s.jpg" width="199" height="136" border="0" alt="js" hspace="5" class="pict" align="right"  /></a></p>

<p>講師をされた　@masuidrive さん、@kurain さん、主宰者の@t32k さん、おつかれさまでしたー !</p>











<p>次回はTitaniumハンズオンが予定されているようですね。<a href="http://www.android-group.jp/index.php?%A5%EF%A1%BC%A5%AD%A5%F3%A5%B0%A5%B0%A5%EB%A1%BC%A5%D7%2F%B6%E2%C2%F4%BB%D9%C9%F4%2F%C2%E8%B6%E5%B2%F3%CA%D9%B6%AF%B2%F1" target="blank">こちら</a>も楽しみです。がんばってください！</p>

<p>ライブドア技術部会より</p>



























</div>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66560080" width="1" height="1" />
]]>
</content:encoded>
</item>
<item rdf:about="http://blog.livedoor.jp/techblog/archives/66528186.html">
<title>なんでもありのWebアプリケーション高速化バトル、#isucon 開催のお知らせ</title>
<link>http://blog.livedoor.jp/techblog/archives/66528186.html</link>
<description>こんにちは、ライブドア技術部会の櫛井です。
Webサービスの高速化に取り組んでいる全てのエンジニアに存分にその腕をふるってもらうべく、ライブドアがサーバ100台を準備してイベントを行います。いい感じにスピードアップコンテスト、略して ISU Contest (Iikanjini Speed ...</description>
<dc:creator>kushii_</dc:creator>
<dc:date>2011-07-21T13:56:02+09:00</dc:date>
<dc:subject>お知らせ</dc:subject>
<content:encoded><![CDATA[<div class="section">
<p>こんにちは、ライブドア技術部会の櫛井です。</p>
<p>Webサービスの高速化に取り組んでいる全てのエンジニアに存分にその腕をふるってもらうべく、ライブドアがサーバ100台を準備してイベントを行います。いい感じにスピードアップコンテスト、略して <b>ISU Contest (Iikanjini Speed Up Contest)  #isucon</b> です！レギュレーション事前公開、細かいルール無用のチームバトル。腕に覚えのあるエンジニアにはぜひ参加していただきたい！</p>
<p>なお、<b>参加者募集の開始は7月28～29日頃を予定</b>しています。Ustream等による中継はございませんので、ぜひ直接ご参加ください！</p>

<p><h3>レギュレーション概要 </h3></p>
<p>レギュレーション詳細は後日、参加募集の際に全て発表します。現状は概要のみでご容赦ください。また詳細が変更される場合があります。(参加応募開始時に公開するものからは変更されません。)</p>

<ul>
<li>ライブドアが準備したWebアプリケーションに対してライブドアブログから抽出したアクセスパターンの負荷をかけ、性能を競う
<ul>
<li>Perlで記述されたWebアプリケーションを基準アプリケーションとして提供します</li>
<li>他の言語による参考実装も提供されるかもしれません</li>
</ul>
</li>
<li>チーム単位(1～3人)での参加とし、チームごとに最大5台のLinuxサーバが与えられる
<ul>
<li>リバースプロキシ、Web/AP(2台)、DB、その他の用途、の計5台で計画中です</li>
</ul>
</li>
<li>与えられたWebアプリケーションにおける以下の機能を変えないこと
<ul>
<li>アクセス先のURI</li>
<li>レスポンス(HTML)のDOM構造</li>
<li>ブラウザで表示した際の見た目(問題ない範囲で)、およびJavascript/CSSの効果</li>
</ul>
</li>
<li>サーバ再起動を行っても設定・データの永続性が保たれていること</li>
<li>負荷走行中にPOSTされたデータがxx秒以内にGETリクエストへのレスポンスに反映されること(検討中)</li>
<li>これらのレギュレーション項目が守られればいかなる変更も可とする
<ul>
<li>HTMLやJS/CSSなど、コンテンツの最適化</li>
<li>DBスキーマの変更やインデックスの作成・削除、キャッシュ機構の追加、jobqueue機構の追加による遅延書き込み (レギュレーションのデータ反映条項を満たすこと)</li>
<li>他の言語による再実装</li>
</ul>
</li>
</ul>
<p>などなど</p>


<p><h3>募集要項</h3></p>
<p>チーム単位での参加募集を行います。申し込みは先着順とします。チーム構成は1人から最大3人までとし、その他には特に制限はありません。</p>
<p>ルール上、短い時間でOSからミドルウェア・アプリケーションまで様々な部分に手を入れる必要がありますので、チームでの参加を強くお勧めします。(ただし一人で何から何まで超強力に実装してしまえるスーパーエンジニアについてはこの限りではありません。)</p>

<p>また会場での作業用に、無線LANが使用可能なノートPCをそれぞれお持ちください。主催側で無線LANネットワークを用意しますが、作業用端末は準備いたしません。</p>

<ul>
<li>会場</li>
</ul>
<p>新宿エルタワー</p>
<ul>
<li>日程</li>
</ul>
<p>8月27日 10:00～19:00 (18:00作業終了、以降 結果測定、表彰、講評)</p>
<p>優勝・準優勝チーム等には賞品が出る予定です！</p>

<p>また、19時より懇親会も行う予定です。</p>



<p>では腕に覚えのある皆さん、予定を空けておきつつチームメンバー予定な方に声かけておいてくださいね！大事なことなので二回書きますが、参加者募集の開始は7月28～29日頃を予定しています。</p>
</div>

<img src="http://counter2.blog.livedoor.com/c?ro=1&act=rss&output=no&id=2087405&name=techblog&pid=66528186" width="1" height="1" />
]]>
</content:encoded>
</item>

</rdf:RDF>

