Buttonのクリックイベント

Buttonのクリックイベントのハンドリング方法について説明する。

Buttonのクリックイベントを扱うにはButtonクラスのsetOnClickListener()メソッドでView.OnClickListenerクラスを設定する。
これによりButtonをクリックすると設定したView.OnClickListenerクラスのonClick()メソッドが呼び出される。

公式ドキュメントには下記の2種類のイベントハンドリング方法が記載されていた。
それぞれの方法で利点と欠点があるので場合によって使い分ける必要がでてきそうだ。

方法1

public class TestActivity extends Activity {
 protected void onCreate(Bundle savedValues) {
  Button button = (Button)findViewById(R.id.Button01);
  button.setOnClickListener(new OnClickListener() {
   public void onClick(View v) {
    //ここにボタンがクリックされた際に行う処理を記載する
   }
  });
 }
}

方法2

public class TestActivity extends Activity implements OnClickListener {
 protected void onCreate(Bundle savedValues) {
  Button button = (Button)findViewById(R.id.Button01);
  button.setOnClickListener(this);
 }
 public void onClick(View v) {
  //ここにボタンがクリックされた際に行う処理を記載する
 }
}

書籍「時間管理で夢を実現する」

書籍「時間管理で夢を実現する」を読んだのでそれについて記載しようと思う。

まずなぜこの本を読んでみようかと思ったというと最初の22ページまでに書いてある内容がずばり自分のことじゃないかと思うような内容だったからだ。

やってみたいこと(夢)があるのだがいろいろな誘惑に負けて明日やろう、明後日やろうっと先延ばしになる。そして何も実現できずに時間が過ぎてしまっている。日々の生活にこんなことを考えたことがある人は読んでみてみるといいと思う。ほんの少しだけだが前に進もうと思えるようになるかもしれない。

さてここからはこの本で重要だと思われる部分を自分のために要約しておこうと思う。
ネタばれが嫌な方は読むのをやめて本やまたは図書館に行くことをおすすめする。

まず重要なことは行動を緊急と重要の2つのことがらに注目して分類してみるということだ。
つまり行動を下記の4種類に分類する。

  • 緊急であり重要な行動(第1領域)
  • 緊急ではないが重要な行動(第2領域)
  • 緊急であるが重要ではない行動(第3領域)
  • 緊急ではなく重要ではない行動(第4領域)

第1領域は緊急であり重要な行動なのでかならずやらなくてはならない行動であるため、誰しもこの領域の行動がおろそかになることはあまりない(はずですよね?w)ただ緊急であり重要な行動なため、この領域の作業が多くなるとストレス&疲労が溜まってしまう。理想としてはこの領域に入る行動を少なくすることである。

第2領域は緊急ではないが重要な行動である。この領域に入る行動が一番実行するのが大変なものである。緊急性がないため、どうしても先延ばしにしてしまう。そうなると期限があるものの場合、時間が経過するとその行動は第2領域から第1領域に移ってしまう。つまり第2領域をサボっていると第1領域の行動が増えてストレス&疲労が溜まるような生活をおくることになる。

第3領域は緊急であるが重要ではない行動である。この領域は緊急性があるため、サボることはあまりない。しかし重要ではないため、なぜこんなことをしているんだろう?など不満が溜まることになる。できればこの領域を減らして第2領域の行動を増やせるようにするべきである。

第4領域は緊急ではなく重要ではない行動である。この領域にゲームやら娯楽関連が入る。(ただし私は気分転換として計画をたて管理して行う分にはこの領域には入らないと思う。必要な休息もとらずにひたすら頑張るとかならずあとで燃え尽きてしまうと思う。)この領域がなかなかの曲者で緊急性も重要性もないのにどっぷりとハマってしまう。この領域は減らす方がよいと分かっているんだが抜けられないんだよねw。

ここからの要約はかなり粗くする。なぜならば他の時間管理に関する本と似通っている部分が多いからである。(どの本にも出てくるということは重要なことですけどね)もう既にこの内容は知っている可能性が高いこととこの本意外の時間管理の本を読んでも同じないようを知ることできるため、詳しくは記載しないこととする。

まず自分の価値観を言葉にしてみる。つまり自分にとって何が大事か?それを考え言葉として書き出してみることである。書き出して言葉にしないとぼやけてほんとに何が自分にとって大切なことか意外とわからないものである。

次に役割について考えることである。
職場や家庭での役割を考えることで自分が果たすべき責任が明確になる。

上記の価値観と役割を元にして目標を決定する。
目標は下記の5つのポイントに気をつけるべきである。

  • 具体的である
  • 計測できる
  • 行動を促すものである
  • 現実的である
  • イムリーである

上記の5つのポイントがかけていると目標は絵に描いた餅になってしまう。

そして立てた目標を細分化して日々の行動に落とし込みやすくする。そして細分化した各行動に優先順位と期限をつける。
この優先順位と期限をつけた行動を1週間と1ヶ月の目標として設定する。

1週間の目標が決まったらこれを実現するために1週間の計画を立てる。1週間という単位は自分の生活のバランスを考えるのに最適である。計画を立てるとき重要なのは重要な行動からスケジュールの中に組み込んでいくことである。重要でもない行動からスケジュールを入れてしまうと重要な行動を入れることができなくなるかもしれないからだ。

ここまでできたらあとは毎日15分ほどの時間を使って1日の計画を立てる。計画を立てたらあとは実際に行動するだけである。

さてここまで本の内容を書いてきたが書いてあることは至極真っ当なことである。しかし三日坊主な自分にできるのか不安な点がある。
ま〜、とりあえず行動してみないことには前には進めないので多少間違っていても行動を起こしてみようと思う。

Android開発環境のセットアップ

Java SDKをインストールする

sudo apt-get install sun-java6-jdk

Eclipseをインストールする。

なおEclipseのバージョンは3.4以上をインストールすること。
この3.4以下だと昔うまく設定できずにはまった記憶があります。

sudo apt-get install eclipse

Android SDKをインストールする

http://developer.android.com/sdk/index.htmlからAndroid SDKをダウンロードして解凍。

tar zxvf android-sdk_r05-linux_86.tgz 

解凍したディレクトリにあるtoolsにパスを通しておいた方が便利なので
~/.bash_profile、または~/.bashrcに下記を追記する。

export PATH=${PATH}:<解凍したディレクトリ>/tools

必要なパッケージをダウンロードする。

ダウンロードする方法はtoolsの下にあるandroidコマンドを実行する。
実行するとAndroid SDK and AVD Managerウインドウが開くのでAvailable Packagesを選択して必要なパッケージをインストールする。

AVDの作成

androidコマンドで表示されるウインドウのVirtual DeviceをクリックしてNewボタンを押す。
AVDの設定についてあれこれ設定する画面がでてくるのでターゲットとしたいデバイスのスペックを参考にして作成する

EclipseにADTをインストールする。

Eclipse を起動、メニューから Help > Install New Software を選択。以下の2つを追加する。

EclipseAndroidの設定を行う

メニューのWindow - Preferenceを選択。
開いたWindowのAndroidをクリックし、SDK LocationにインストールしたAndroid SDKの場所を入力する。

これでインストールは完了。
あとはFile - New - ProjectでAndroid Projectを作成してアプリが作れます

1次元テクスチャの作成方法

今回は1次元テクスチャの作成方法について記載する。

これを書く前に1次元テクスチャを表示させるサンプルを作成していたのだが上手くいかず2、3日悩んでしまった。
原因は1次元テクスチャ作成前にglDisableでGL_TEXTURE_2Dを無効にしておく必要があったのだ。glEnableでGL_TEXTURE_1Dを有効にするってことは理解できるのだがGL_TEXTURE_2Dを無効にする必要があるとは思わなかった。なんでそれが必要なのか気になるので時間があるときにでも調べておこう。

前置きが長くなってしまったが作成方法は下記のようになる。

#define TEXSIZE 64

GLubyte bits[TEXSIZE][3];

for (i = 0 ; i < TEXSIZE ; i++) {
 bits[i][0] = (GLubyte)255;
 bits[i][1] = 0;
 bits[i][2] = 0;
}

GLubyte texNmae;
glEnable(GL_TEXTURE_1D);
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_1D, texName);

glTexImage1D(GL_TEXTURE_1D , 0, GL_RGB, TEXSIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, bits);

ほとんど作成方法は2次元テクスチャと変わらない感じになる。使用方法も2次元テクスチャと同じで描画前にglEnable(GL_TEXTURE_1D)、glBindTexture(GL_TEXTURE_1D, texName)を呼び出すだけである。

かなりゆっくりであるがだんだんopenGLがどんなものか分かってきたぞ。まだまだ先が長いが頑張るかの

オフスクリーンレンダリング

オフスクリーンレンダリングができないとあれこれやりたいことができなくて困りそうなので調べてみた。

調べてみておどろいたのだがopenGLはオフスクリーンレンダリング拡張機能を使用しないといけないらしい。
う〜む、DirectXだとだいぶ前からオフスクリーンレンダリングは当たり前にできていたのだがなぜこんな扱いになってるんだろうな。

さてオフスクリーンレンダリングの方法を簡単に説明するとフレームバッファというものを作成し、フレームバッファレンダリング先となるテクスチャを関連付ける。
あとはレンダリングを行う前にglBindFramebufferEXT()でレンダリング先となるフレームバッファをバインドすればフレームバッファと関連づけたテクスチャに描画される。
(テクスチャに描画されているのか、フレームバッファに描画されているのかどちらの表現の方が正しいのか詳しく調べてないのでちと自信がないな)

さてそれはおいといて今回は初期化等やら面倒なのでglewを使用することにした。
glewを使うにはGL/glew.hをインクルードしてMakefileに-lGLEWを追加してライブラリをリンクする。

まずオフスクリーンレンダリングで描画するターゲットとなるテクスチャを作成する。
作成するテクスチャはRGBを書き込むテクスチャとDepthを書き込むテクスチャの2つである。2Dの描画だけ行うならばDepthの方が必要ないようだ。

glGenTextures(1, &targetTextureRGB);
glBindTexture(GL_TEXTURE_2D, targetTextureRGB);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glGenTextures( 1, &targetTextureDepth );
glBindTexture( GL_TEXTURE_2D, targetTextureDepth );
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0 );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

次にフレームバッファの作成だがその前にGLEWの初期化とフレームバッファに対応しているか調べないといけない。対応していない場合はどうしようか迷うがとりあえずサンプルなのでエラーメッセージを表示するだけにしておこう。

if ( glewInit() != GLEW_OK ) {
 std::cout << "Error : GLEWの初期化に失敗しました\n";   
}

if (! GLEW_EXT_framebuffer_object ) {
 std::cout << "Error : フレームバッファオブジェクトがサポートされていません\n";        
}

やっと本題のフレームバッファの作成に入る。基本的には作成してターゲットとなるテクスチャをアタッチするだけである。忘れてはならないのは作成したあとにglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 )を呼び出してターゲットを元に戻しておかないとひどい目を見ることになる。

glGenFramebuffersEXT(1, &fboID);
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, targetTextureRGB, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, targetTextureDepth, 0 );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );

あとは描画する前に(glBeginの前)にglBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fboID )を呼び出して描画先を変更して描画する。

上記の方法で描画先をテクスチャに変更できた。さてこれで次の作業に進める

テクスチャの作成&描画方法

まずテクスチャを作成する前にglEnable(GL_TEXTURE_2D)を呼び出して2Dテクスチャを有効にする必要がある。

glGenTextures()関数を使ってテクスチャ名を作成する。DirectXをやっていたからテクスチャ名を作成するっていうのは何かしっくりこないがそういうものらしい。

次にglBindTexture()関数を呼び出してテクスチャターゲットとテクスチャ名をバインドする。これでこのテクスチャ名の次元を設定できる。

次に下記の関数を呼び出してフィルタの設定を行う。この設定を行ってないとテクスチャが表示されなかった。これを呼び出してないサンプルプログラムも存在するので環境によって違うのかもしれない。

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);		

そしてglTexImage2D()関数でテクスチャに画像を設定する。

ここまでのテクスチャ作成のサンプルを下記に記録しておく。

glEnable(GL_TEXTURE_2D);
	
glGenTextures(1, &texture1);
glBindTexture(GL_TEXTURE_2D, texture1);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);		

GLubyte bits[64][64][3];
for(int i = 0; i < 64; i++) {
 int r = (i * 0xFF)/64;
 for(int j = 0; j < 64; j++) {
  bits[i][j][0] = (GLubyte)r;
  bits[i][j][1] = (GLubyte)((j * 0xFF)/64);
  bits[i][j][2] = (GLubyte)~r;
  }
}
glTexImage2D(GL_TEXTURE_2D, 0, 3, 64, 64, 
             0, GL_RGB, GL_UNSIGNED_BYTE, bits);

テクスチャを使った描画で気をつける点は描画する前にglBindTexture()関数を呼び出して使用するテクスチャを設定することぐらいだろう。あとは下記のように記述すればテクスチャを貼ったポリゴンが描画される(はず)。

glBegin(GL_POLYGON);

glBindTexture(GL_TEXTURE_2D, texture1);		

glTexCoord2f(0, 0); glVertex2d(0.1, 0.1);
glTexCoord2f(0, 1); glVertex2d(0.1, 0.9);
glTexCoord2f(1, 1); glVertex2d(0.9, 0.9);
glTexCoord2f(1, 0); glVertex2d(0.9, 0.1);
	
glEnd();

Qt4でのopenGLの初期化方法

Qt4でのopenGLの初期化方法を忘れないように記録しておく。

qmake qtTest.pro
make

main.cpp

#include <qapplication.h>

#include "qopengl.h"

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);

  QopenGL* gl = new QopenGL;
  gl->resize(640, 480);

  //app.setMainWidget(gl);
  gl->show();
  return app.exec();
}

qopengl.h

#ifndef QOPENGL_H
#define QOPENGL_H
#include <qgl.h>

class QopenGL : public QGLWidget
{
  Q_OBJECT

public:
  QopenGL( QWidget *parent = 0 , const char *name = 0 );

protected:
  void initializeGL();
  void resizeGL(int width, int height);
  void paintGL();

};

#endif

qopengl.cpp

#ifndef QOPENGL_H
#define QOPENGL_H
#include <qgl.h>

class QopenGL : public QGLWidget
{
  Q_OBJECT

public:
  QopenGL( QWidget *parent = 0 , const char *name = 0 );

protected:
  void initializeGL();
  void resizeGL(int width, int height);
  void paintGL();

};

#endif

qtTest.pro

TEMPLATE = app
TARGET = 
DEPENDPATH += .
INCLUDEPATH += .
QT += opengl

# Input
HEADERS += qopengl.h
SOURCES += main.cpp qopengl.cpp