VRAMを使う



VRAMにはウィンドウの画面のRGBデータがすべて格納されています。
ウィンドウの画像をすべて配列変数に入れることが出来るので、画像の読みとりにも便利です。
そして、そのVRAMの内容を書き換えることにより、実際の画面も書き換えられるのです。
実際の画面に描画しているわけではないので、pgetやpsetを使って処理するよりも高速です。

 mref vram,66

これで変数vramにウィンドウ画像のデータが格納されました。
やっかいなのは、VRAMのデータは、HSPのウィンドウとは違い、座標は左上から右下ではなく、左下から右上へという風になっているのです。
普通に取り出していては、データは任意の座標の縦180度反転した位置を取りだしてしまいます。これでは面倒です。
そこで、任意の座標を指定するための式があります。
x,yを取り出したい座標とすると、

 ((winy-1-y)*winx*3)+(x*3)
 カッコを外して
 winy-1-y*winx+x*3

カッコ付きの方がわかりやすいと思いますが、カッコはない方が少しは早いので、出来るだけ外した方がいいと思います。
またこれは、フルカラーモード時の式なので、パレットモードの時は*3を抜いてください。それで出来ます。

 mref vram,66
 vpos=winy-1-y*winx+x*3
 peek b,vram,vpos
 peek g,vram,vpos+1
 peek r,vram,vpos+2

注意すべき点は、格納されている順番がRGBではなくBGRになっているということです。
なぜかは私もわかりません。まぁそういう仕様なんでしょう。
あともう1つ注意しなければならないことは、VRAMの内容を書き換えても、画面に反映させるには画面の更新、つまり再描画をしなければなりません。よってredrawを使用してください。
それではサンプルを作ってみましょう。今回は色反転の処理を行います。

	;フルカラーモード専用です

	screen 0,300,300

	redraw 0
	repeat winx
		color cnt*255/winx,255,-cnt*255/winx+255
		line cnt,-1,cnt,winy
	loop
	redraw 1
	;--------------------------------------------------------------------
	;画像ファイルを使わないため、反転の効果を見るためいろいろな色を使う。
	;色の式についてはあまり気にしないでください。
	;反転がわかりづらかったら、各自で好きな画像を読み込んでみてください。
	;--------------------------------------------------------------------
	
	mref vram,66		;VRAM画面データ読みだし

	startx=100		;反転をスタートするx座標
	starty=100		;反転をスタートするy座標
	sizex=100		;反転させる大きさx
	sizey=100		;反転させる大きさy

	;ここから画面処理
	repeat sizey
		ycnt=cnt		;二重ループのため
		repeat sizex
			vpos=winy-1-starty-ycnt*winx+startx+cnt*3
			;((winy-1-(starty+ycnt))*winx*3)+((startx+cnt)*3)を展開したもの
			peek cb,vram,vpos			;色を取り出す
			peek cg,vram,vpos+1
			peek cr,vram,vpos+2
			poke vram,vpos,255-cb		;反転した色をVRAMに書き込む
			poke vram,vpos+1,255-cg
			poke vram,vpos+2,255-cr 
		loop
	loop

	redraw 1		;画面に反映させる

	stop

pget,psetでの反転との速度の違いを試してみてください。以下がpget,psetのスクリプトです。

	;pget,psetによる色の反転

	screen 0,300,300

	redraw 0
	repeat winx
		color cnt*255/winx,255,-cnt*255/winx+255
		line cnt,-1,cnt,winy
	loop
	redraw 1

	startx=100		;反転をスタートするx座標
	starty=100		;反転をスタートするy座標
	sizex=100		;反転させる大きさx
	sizey=100		;反転させる大きさy

	redraw 0
	repeat sizey
		ycnt=cnt
		repeat sizex
			pget startx+cnt,starty+ycnt
			color 255-rval,255-gval,255-bval
			pset startx+cnt,starty+ycnt
		loop
	loop
	redraw 1

	stop

VRAMを使うことで画面に直接アクセスする事がになりましたが、書き換えについてはあまり大きな利点はありません。
色の反転はwinAPIのInvertRect関数でできるし、半透明コピーや色加算・減算コピーは普通にgmode&gcopyで出来てしまいます。
白黒化するときやそれ以外の特殊な処理をするにも、反転、α合成以外はなかなか使う機会はないと思います。
しかし知っておいて損はないし、いずれ使うときが来るかもしれないから、覚えておくべきだとおもいます。



戻る