OpenGLで文字列

OpenGLで文字列を描画したく、いろいろ探してみたのですが、みんな苦労しているみたいです。

とりあえずわかったことが2つ、日本語はちょっと難しい。

  • まずGLUTを使うやり方

これの場合、日本語は描画できません。ただし簡単に書くことができます

http://d.hatena.ne.jp/osyo-manga/20110827/1314417606

こちらのサイトを参考に

-(void)paint{
		glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // default background color
		glClear(GL_COLOR_BUFFER_BIT);
		
		[self renderString:@"kana" x:0.5 y:0.5f];
		glFlush();
}

-(void)renderString:(NSString *)str_ x:(float)x_ y:(float)y_{
		glRasterPos2d(x_, y_);
		const char* charStr=[str_ UTF8String];
		int len=(int)[str_ length];
		for(int i=0;i

  • テクスチャを使うやり方

日本語を表示したい場合にはテクスチャを使うみたいです。結構重いとのことなので決まった文字列の場合には画像をそのまま貼付けた方が良さそうです

http://null-null.net/blog/2007/10/566.php

こちらのサイトを参考に

+ (void) draw:(NSString *)string_	x:(float)x_ y:(float)y_{
	NSAttributedString *attrString;
	GLuint *texId;

		glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
		glClearDepth( 1.0f );
		glDisable(GL_CULL_FACE);
		glEnable( GL_BLEND );
		glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
		
		int i, strSize;
		NSFont *nsfont;
		NSDictionary *attrsDictionary;
		NSAttributedString *singleChar;
		NSImage **images;
		NSBitmapImageRep **imageReps;
		NSImage* img;
		NSPoint point;
		NSSize size;

		int texWidth_=10;
		int texHeight_=10;
		
		// alloc texture id and image buffer
		strSize = (int)[string_ length];
		texId = (GLuint*)malloc( sizeof(GLuint)*strSize );
		images = (NSImage**)malloc( sizeof(NSImage*)*strSize );
		imageReps = (NSBitmapImageRep**)malloc( sizeof(NSBitmapImageRep*)*strSize );
		for( i = 0; i < strSize; i++ ){
				images[i] = [[NSImage alloc] initWithSize:NSMakeSize( texWidth_, texHeight_ )];
		}
		
		// font settings
		NSSize screenResolution = [[[[NSScreen mainScreen] deviceDescription] objectForKey:NSDeviceResolution] sizeValue];
		int fontSize_ = texWidth_ * 72.0/screenResolution.width;
		
		nsfont = [NSFont fontWithName:@"HiraKakuPro-W6" size:fontSize_];
		attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
											 nsfont, NSFontAttributeName,
											 [NSColor whiteColor], NSForegroundColorAttributeName,
											 [NSColor clearColor], NSBackgroundColorAttributeName,
											 nil
											 ];
		
		// alloc attributed string
		attrString = [[NSAttributedString alloc] initWithString:string_ attributes:attrsDictionary];
		
		// create texture id
		glEnable( GL_TEXTURE_2D );
		glGenTextures( strSize, texId );
		
		// build texture image
		for( i = 0; i < strSize; i++ ){
				img = images[i];
				singleChar = [attrString attributedSubstringFromRange:NSMakeRange(i,1)];
				// setting background color
				[img setBackgroundColor:[NSColor clearColor]];
				// calc center position
				size = [singleChar size];
				point = NSMakePoint( (texWidth_-size.width)/2, (texHeight_-size.height)/2 );
				// draw character to image
				[img lockFocus];
				[singleChar drawAtPoint:point];
				[img unlockFocus];
				
				// alloc bitmap image from NSImage
				imageReps[i] = [[NSBitmapImageRep alloc] initWithData:[img TIFFRepresentation]];
				
				// texture settings
				glBindTexture( GL_TEXTURE_2D, texId[i] );
				glTexImage2D(
										 GL_TEXTURE_2D, 0, GL_RGBA,
										 texWidth_, texHeight_, 0,
										 [imageReps[i] hasAlpha] ? GL_RGBA :GL_RGB,
										 GL_UNSIGNED_BYTE,
										 [imageReps[i] bitmapData]
										 );
				glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
				glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
				glBindTexture( GL_TEXTURE_2D, 0 );
		}
		glDisable( GL_TEXTURE_2D );
		
		// release
		for( i = 0; i < strSize; i++ ){
				[imageReps[i] release];
				[images[i] release];
		}
		free( imageReps );
		free( images );
		
	strSize = (int)[string_ length];
	glEnable( GL_TEXTURE_2D );
	for( i = 0; i < strSize; i++ ){
		glBindTexture( GL_TEXTURE_2D, texId[i] );
		glBegin(GL_POLYGON);

						float wf_=0.1f; // TODO Viewのサイズからきちんと求める
						float hf_=0.1f;

						glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
						glTexCoord2f( 0, 1 );
						glVertex2f( x_+i*wf_, y_ );
						glTexCoord2f( 1, 1 );
						glVertex2f( x_+(i+1)*wf_, y_ );
						glTexCoord2f( 1, 0 );
						glVertex2f( x_+(i+1)*wf_, y_+hf_ );
						glTexCoord2f( 0, 0 );
						glVertex2f( x_+i*wf_, y_+hf_);
		glEnd();
	}
	glDisable( GL_TEXTURE_2D );

		glDeleteTextures((int) [string_ length], texId );
		free( texId );
		[attrString release];
}

ちょっといい加減ですがこんな感じ

NSViewでmouseMoved

デフォルトではmouseMovedを継承してもイベントは拾えないみたいです

http://stackoverflow.com/questions/7543684/mousemoved-not-called

この辺り参照

- (id)initWithFrame:(NSRect)frameRect_ pixelFormat:(NSOpenGLPixelFormat*)format_
{
		if(self=[super initWithFrame:frameRect_ pixelFormat:format_]){
				NSTrackingArea* trackingArea_ = [[NSTrackingArea alloc] initWithRect:[self bounds] options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveInKeyWindow | NSTrackingEnabledDuringMouseDrag ) owner:self userInfo:nil];
				[self addTrackingArea:trackingArea_];
				[trackingArea_ release];
				NSMutableArray* removeBeforePaintList_=[[NSMutableArray alloc]init];
				removeBeforePaintList=removeBeforePaintList_;
				alreadySetUp=false;
				[self setupCanvas];
		}
		return self;
}

-(void)updateTrackingAreas
{
		if(trackingArea){
				[self removeTrackingArea:trackingArea];
		}
		NSTrackingArea* trackingArea_=[[NSTrackingArea alloc]initWithRect:[self frame] options:(NSTrackingMouseEnteredAndExited |
																																								NSTrackingMouseMoved |
																																								NSTrackingActiveAlways )
																										owner:self
																								 userInfo:nil];
		[self addTrackingArea:trackingArea_];
		[trackingArea_ release];
	 
}

こんな感じでいいのでしょうか?

NSNumberの拡張?

どうもCocoaプログラミングでは通常のC言語のような数値配列を使うことはできなさそう。

NSNumberとNSMutableArrayを駆使して書くのが一般的みたいです。

ただ、NSNumberだと一回作ったオブジェクトの値がどうやら変更不可らしい。

これでは数値計算には使えません。

そこでNSNumberを拡張してみました

@interface MYNUmber:NSNumber{

}

@property(readwrite)float floatValue;

@property(readwrite)bool boolValue;

@property(readwrite)int intValue;

@property(readwrite)double doubleValue;

@end

これでとりあえずコンパイルは通りました

initialization method -initWithInt: cannot be sent to an abstract object

が、allocする際に何やらエラー。。

まだ道のりは遠い。。

MacPortsのインストール

最近Macプログラミングにはまっています。

ところでリソースからpngファイルをNSImageに取り込もうとしているのですがうまくいきません。

とりあえずpngを他の画像ファイルに変更するためにImageMagick を使おうとしたのですがデフォルトでは入っていない模様。。

http://distfiles.macports.org/MacPorts/

こちらからMacPortsなるものをインストール

/opt/local/binにインストールされるみたいです

自動で~/.profileも作成されるみたい。

プロキシ環境だと.profileに

export http_proxy=http://server:port

を付け加えておきます

これでいざ

$ sudo port search imagemagick
Warning: Can't open index file for source: rsync://rsync.macports.org/release/tarballs/ports.tar
Error: search for name imagemagick failed: No index(es) found! Have you synced your source indexes?
No match for imagemagick found

ないんかい!

素直にこれを入れればいいことが判明。

http://cactuslab.com/imagemagick/

Macをサーバに、windows7をクライアントにしてSynergyでつなげてみる

以前、Windows7をサーバに、Mac をクライアントにして Synergyで連携してみました。

そのときの構成は

  • Windows7+Synergy1.4.10
  • maxOX10.8 +SynergyKM1.3

この組み合わせで、Macのキーボード野設定をオーストラリアにすることにより、記号なども問題なく使えることを発見

今度は逆にMacをサーバにしてみることにします

  • Windows7+Synergy1.3.8
  • maxOSX10.8+SynergyKM1.3

Windows側はSynergyのバージョンを落とさないとつながらない模様。

ただしこの場合だとWindows側に入った際に日本語の切り替えがキーボードからできません。

CmdSpaceなるものをインストールしてみたもののうまくいかない。

そこで、WindowsのIMEの設定を変更します

http://www.relief.jp/itnote/archives/001818.phpこの記事を参考に

IMEのプロパティー全般の編集操作のキー設定を変更します。

ctrl+spaceを半角全角切り替えに設定すればOK

Xcode4.5ではまったのでメモ

最近XCodeのcocoaでmacアプリなんぞ作ろうとしています。

そこで

https://developer.apple.com/jp/documentation/Cocoa/Conceptual/ObjCTutorial/01Introduction/chapter_1_section_1.html#//apple_ref/doc/uid/TP40000863-CH13-DontLinkElementID_63などというページを参考にサンプルアプリケーションを作ることにします。

かなり古い資料なので、若干今のXcode4.5 と違っていたりしますがそこは心眼でよみつつ。

その中でも一番悩んだのがここ↓

https://developer.apple.com/jp/documentation/Cocoa/Conceptual/ObjCTutorial/06Controller/chapter_6_section_6.html#//apple_ref/doc/uid/TP40000863-CH8-DontLinkElementID_47

どう見てもこのインスタンスを作成することができない。。

悩むこと1日。ようやくわかりました

XCodeの右下にあるObjectLibraryから「Object」なるものをnibに追加。

Objectを選択し、CustomClassでControllerのクラス名を入れる。そうすれば

フィールドと接続できるようになりました。

もっとマニュアルやらチュートリアルを最新版にあわせて充実させてほしいものです。

Macでzcat

最近、UnixとWindowsのあいのこであるようなMacにすっかりはまってます

LinuxからMacへといろいろなシェルなどを移植中

zcatではまったのでメモ

Apacheのログを解析しようと、ZCATで解凍しようとしたのですが、何度やっても↓

$ zcat acc2012-03-01.gz
zcat: acc2012-03-01.gz.Z: No such file or directory

http://nomorework.fool.jp/wordpress/2012/01/28/macのzcatではgzを開けない/

いろいろ調べたところありました。こちらの記事を参考にzcatをgzcatに変更すればOK

$ gzcat acc2012-03-01.gz
...

Macにffmpegをインストールしてみた

http://jungels.net/articles/ffmpeg-howto.html:このあたり]を参考にインストールしてみる。

  • 環境;MacOSX 10.8.2

lame

コーディックらしい。たぶん。。

# tar xcvfp lame-3.99.5.tar
# cd lame-3.99.5
# ./configure
# make
# make istall

faad2

# tar xvfp faad2-2.7.tar
# cd faad2-2.7
# ./configure
# make
# make install

ffmeg

# git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
# tar zxvfp ffmpeg-1.0.tar.gz
# cd ffmpeg-1.0
# ./configure --enable-libmp3lame --enable-shared --disable-mmx --arch=x86-64
# make
# make install

mp4からmp3に変換してみる

ディレクトリにXXXX.mp4というファイルを複数入れているとする

# for f in *mp4;do
> ffmpeg -i $f -ab 128 ${f%.*}.mp3
> done

MacでHadoop(インストール)

http://www.ne.jp/asahi/hishidama/home/tech/apache/hadoop/pseudo.html:こちら]とhttp://d.hatena.ne.jp/daisuke-m/20110605/1307239347:こちら]を参考にインストールする

wgetのインストール

特になくてもいいのだが後々便利なので入れておく

$ cd /Users/UserName/Download
$ tar zxvpf wget-1.14.tar.gz
$ cd wget-1.14
$ ./configure
$ make
$ su -
# make install
  • これで/usr/local/bin以下にインストールされる

hadoopのダウンロード

http://www.apache.org/dyn/closer.cgi/hadoop/common/:このあたり]から好きなのを選んでwgetでダウンロード。今回は0.20.205をチョイス

$ cd ~/Download
$ wget http://ftp.jaist.ac.jp/pub/apache/hadoop/common/hadoop-0.20.205.0/hadoop-0.20.205.0-bin.tar.gz
$ tar zxvfp hadoop-0.20.205.0-bin.tar.gz
$ su -
# mv hadoop-0.20.205 /usr/local
# cd /usr/local
# ln -s hadoop-0.20.205 hadoop
# chown -R admin:staff hadoop-0.20.205
# cd hadoop
# ln -s /var/log logs

面倒なのでパーミッションを自分にしておく。あとログのディレクトリも作成

hadoopの設定

  • /usr/local/hadoop/conf/hadoop-env.sh
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Home
export HADOOP_HOME_WARN_SUPPRESS="TRUE"

Javaの環境変数の設定と、HADOOP_HOME is deplicated のWarningが出るのでその対策を入れておく

  • /usr/local/hadoop/conf/core-site.xml


	fs.default.name
	hdfs://localhost:9000


	hadoop.tmp.dir
	/usr/local/hadoop/tmp


  • /usr/local/hadoop/conf/hdsf-site.xml


	dfs.replication
	1


  • /usr/local/hadoop/conf/mapred-site.xml


	mapred.job.tracker
	localhost:9001


	mapred.system.dir
	/mapred/system


  • ~/.bashrc
. /usr/local/hadoop/conf/hadoop-env.sh
export HADOOP_OPTS="-Djava.security.krb5.realm=OX.AC.UK -Djava.security.krb5.kdc=kdc0.ox.ac.uk:kdc1.ox.ac.uk"

export CLICOLOR=1
export LSCOLORS=DxGxcxdxCxegedabagacad

alias dfsls='/usr/local/hadoop/bin/hadoop dfs -ls'			 
alias dfsrm='/usr/local/hadoop/bin/hadoop dfs -rm'			 
alias dfscat='/usr/local/hadoop/bin/hadoop dfs -cat'		 
alias dfsrmr='/usr/local/hadoop/bin/hadoop dfs -rmr'		 
alias dfsmkdir='/usr/local/hadoop/bin/hadoop dfs -mkdir' 
alias dfsput='/usr/local/hadoop/bin/hadoop dfs -put'	 
alias dfsget='/usr/local/hadoop/bin/hadoop dfs -get'		 
alias hadoop='/usr/local/hadoop/bin/hadoop'

これであっているのでしょうか。。

Hadoopを動かしてみる

$ cd ~/Documents/hadoop
$ cat > test.txt
test test test hoge hoge
$ dfsmkdir input
$ dfsput test.txt input
$ dfsls input
Found 1 items
-rw-r--r--	 1 admin supergroup					2 2012-10-02 10:11 /user/admin/input/users.txt

とりあえず動いているみたいだ

Hadoopのエラー

いろいろ試行錯誤しながらやっていると時々わけのわからないエラーが出ます。

$ dfsput test.txt input/
12/10/02 10:06:24 WARN hdfs.DFSClient: DataStreamer Exception: org.apache.hadoop.ipc.RemoteException: java.io.IOException: File test.txt could only be replicated to 0 nodes, instead of 1
	at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:1531)

対処法はごくシンプル

$ /usr/local/hadoop/bin/stop-all.sh
$ rm -rf /usr/local/hadoop/tmp/*
$ hadoop namenode -format
$ /usr/local/hadoop/bin/start-all.sh

macのビープ音を削除してみる

macでTerminalを使用しているとビープ音が耳障りです。

terminalのビープ音

ターミナルを起動して

$ cat > ~/.inputrc
set bell-style none
^C

ターミナルを再起動すればOK.ユーザごとに設定が必要です

VIのビープ音

$ cat > ~/.vimrc
set visualbell t_vb=
^C